3 % Copyright
1996-2006 Han The Thanh
<thanh@@pdftex.org
>
4 % Copyright
2006-2012 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
/>.
27 #include
<kpathsea
/config.h
> /* this is a trick to load mingw32's io.h early
,
28 using a macro redefinition of |eof
()|.
*/
29 #include
"sys/types.h"
30 #include
<kpathsea
/c-stat.h
>
31 #include
<kpathsea
/c-fopen.h
>
34 #include
<float.h
> /* for |DBL_EPSILON|
*/
38 #include
"lua/luatex-api.h" /* for luatex_banner
*/
43 /* POPPLER_VERSION is defined in poppler-config.h for poppler from
44 * the TeX Live tree
, or in the Makefile for an installed version.
*/
45 #include
"poppler-config.h"
48 #define check_nprintf
(size_get
, size_want
) \
49 if
((unsigned
)(size_get
) >= (unsigned
)(size_want
)) \
50 formatted_error
("internal","snprintf failed: file %s, line %d", __FILE__
, __LINE__
);
52 char
*cur_file_name
= NULL;
53 static char print_buf
[PRINTF_BUF_SIZE
];
57 /* define |char_ptr|
, |char_array|
, and |char_limit|
*/
58 typedef char char_entry
;
62 #define SUBSET_TAG_LENGTH
6
63 void make_subset_tag
(fd_entry
* fd
)
65 int i
, j
= 0, a
[SUBSET_TAG_LENGTH
];
69 struct avl_traverser t
;
70 md5_byte_t digest
[16];
72 static struct avl_table
*st_tree
= NULL;
74 st_tree
= avl_create
(comp_string_entry
, NULL, &avl_xallocator);
76 assert
(fd-
>gl_tree
!= NULL);
77 assert
(fd-
>fontname
!= NULL);
78 assert
(fd-
>subset_tag
== NULL);
79 fd-
>subset_tag
= xtalloc
(SUBSET_TAG_LENGTH
+ 1, char
);
82 avl_t_init
(&t, fd->gl_tree);
83 if
(is_cidkeyed
(fd-
>fm
)) { /* |glw_entry| items
*/
84 for
(glw_glyph
= (glw_entry
*) avl_t_first
(&t, fd->gl_tree);
85 glw_glyph
!= NULL; glw_glyph
= (glw_entry
*) avl_t_next
(&t)) {
87 sprintf
(glyph
, "%05u%05u ", glw_glyph-
>id
, glw_glyph-
>wd
);
88 md5_append
(&pms, (md5_byte_t *) glyph, (int) strlen(glyph));
92 for
(glyph
= (char
*) avl_t_first
(&t, fd->gl_tree); glyph != NULL;
93 glyph
= (char
*) avl_t_next
(&t)) {
94 md5_append
(&pms, (md5_byte_t *) glyph, (int) strlen(glyph));
95 md5_append
(&pms, (const md5_byte_t *) " ", 1);
98 md5_append
(&pms, (md5_byte_t *) fd->fontname,
99 (int
) strlen
(fd-
>fontname
));
100 md5_append
(&pms, (md5_byte_t *) & j, sizeof(int)); /* to resolve collision */
101 md5_finish
(&pms, digest);
102 for
(a
[0] = 0, i
= 0; i
< 13; i
++)
104 for
(i
= 1; i
< SUBSET_TAG_LENGTH
; i
++)
105 a
[i
] = a
[i
- 1] - digest
[i
- 1] + digest
[(i
+ 12) % 16];
106 for
(i
= 0; i
< SUBSET_TAG_LENGTH
; i
++)
107 fd-
>subset_tag
[i
] = (char
) (a
[i
] % 26 + 'A'
);
108 fd-
>subset_tag
[SUBSET_TAG_LENGTH
] = '\
0'
;
112 while
((char
*) avl_find
(st_tree
, fd-
>subset_tag
) != NULL);
113 aa
= avl_probe
(st_tree
, fd-
>subset_tag
);
116 formatted_warning
("subsets","subset-tag collision, resolved in round %d",j
);
120 __attribute__
((format
(printf
, 1, 2)))
121 void tex_printf
(const char
*fmt
, ...
)
125 vsnprintf
(print_buf
, PRINTF_BUF_SIZE
, fmt
, args
);
132 size_t xfwrite
(void
*ptr
, size_t size
, size_t nmemb
, FILE * stream
)
134 if
(fwrite
(ptr
, size
, nmemb
, stream
) != nmemb
)
135 formatted_error
("file io","fwrite() failed");
140 int xfflush
(FILE * stream
)
142 if
(fflush
(stream
) != 0)
143 formatted_error
("file io","fflush() failed (%s)", strerror
(errno
));
148 int xgetc
(FILE * stream
)
150 int c
= getc
(stream
);
151 if
(c
< 0 && c != EOF)
152 formatted_error
("file io","getc() failed (%s)", strerror
(errno
));
157 int xputc
(int c
, FILE * stream
)
159 int i
= putc
(c
, stream
);
161 formatted_error
("file io","putc() failed (%s)", strerror
(errno
));
166 scaled ext_xn_over_d
(scaled x
, scaled n
, scaled d
)
168 double r
= (((double
) x
) * ((double
) n
)) / ((double
) d
);
173 if
(r
>= (double
) max_integer || r
<= -(double
) max_integer
)
174 normal_warning
("internal","arithmetic number too big");
178 @ function strips trailing zeros in string with numbers
;
179 leading zeros are not stripped
(as in real life
)
182 char
*stripzeros
(char
*a
)
184 enum
{ NONUM
, DOTNONUM
, INT, DOT
, LEADDOT
, FRAC
} s
= NONUM
, t
= NONUM
;
186 for
(p
= q
= r
= a
; *p
!= '\
0'
;) {
189 if
(*p
>= '
0'
&& *p <= '9')
195 if
(*p
!= '.'
&& (*p < '0' || *p > '9'))
201 else if
(*p
< '
0' ||
*p
> '
9'
)
206 if
(*p
>= '
0'
&& *p <= '9')
216 else if
(*p
< '
0' ||
*p
> '
9'
)
233 if
((t
== FRAC || t
== DOT
) && r != a) {
235 if
(*r
== '.'
) /* was a LEADDOT
*/
251 void initversionstring
(char
**versions
)
254 "Compiled with libpng %s; using %s\n"
255 "Compiled with zlib %s; using %s\n"
256 "Compiled with poppler version %s\n"
257 "Compiled with mplib version %s\n";
258 size_t len
= strlen
(fmt
)
259 + strlen
(PNG_LIBPNG_VER_STRING
) + strlen
(png_libpng_ver
)
260 + strlen
(ZLIB_VERSION
) + strlen
(zlib_version
)
261 + strlen
(POPPLER_VERSION
)
262 + strlen
(mp_metapost_version
())
265 /* len will be more than enough
, because of the placeholder chars in fmt
266 that get replaced by the arguments.
*/
267 *versions
= xmalloc
(len
);
268 sprintf
(*versions
, fmt
,
269 PNG_LIBPNG_VER_STRING
, png_libpng_ver
,
270 ZLIB_VERSION
, zlib_version
, POPPLER_VERSION
, mp_metapost_version
());
274 void check_buffer_overflow
(int wsize
)
276 if
(wsize
> buf_size
) {
277 int nsize
= buf_size
+ buf_size
/ 5 + 5;
282 (unsigned char
*) xreallocarray
(buffer
, char
, (unsigned
) nsize
);
287 @ the return value is a decimal number with the point |dd| places from the back
,
288 |scaled_out| is the number of scaled points corresponding to that.
291 #define max_integer
0x7FFFFFFF
293 scaled divide_scaled
(scaled s
, scaled m
, int dd
)
308 normal_error
("arithmetic", "divided by zero");
309 } else if
(m
>= (max_integer
/ 10)) {
310 normal_error
("arithmetic", "number too big");
314 for
(i
= 1; i
<= (int
) dd
; i
++) {
315 q
= 10 * q
+ (10 * r
) / m
;
325 @ Same function
, but using doubles instead of integers
(faster
)
327 scaled divide_scaled_n
(double sd
, double md
, double n
)
332 di
= floor
(dd
+ 0.5);
334 di
= -floor
((-dd
) + 0.5);
339 int do_zround
(double r
)
343 if
(r
> 2147483647.0)
345 else if
(r
< -2147483647.0)
356 @ MSVC doesn't have |rint|.
361 double rint
(double x
)