/src/ghostpdl/base/gsmisc.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2023 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* Miscellaneous utilities for Ghostscript library */ |
18 | | |
19 | | /* |
20 | | * In order to capture the original definition of sqrt, which might be |
21 | | * either a procedure or a macro and might not have an ANSI-compliant |
22 | | * prototype (!), we need to do the following: |
23 | | */ |
24 | | #include "std.h" |
25 | | #if defined(VMS) && defined(__GNUC__) |
26 | | /* DEC VAX/VMS C comes with a math.h file, but GNU VAX/VMS C does not. */ |
27 | | # include "vmsmath.h" |
28 | | #else |
29 | | # include <math.h> |
30 | | #endif |
31 | | static inline double |
32 | | orig_sqrt(double x) |
33 | 0 | { |
34 | 0 | return sqrt(x); |
35 | 0 | } |
36 | | |
37 | | /* Here is the real #include section. */ |
38 | | #include "ctype_.h" |
39 | | #include "malloc_.h" |
40 | | #include "math_.h" |
41 | | #include "memory_.h" |
42 | | #include "string_.h" |
43 | | #include "gx.h" |
44 | | #include "gpcheck.h" /* for gs_return_check_interrupt */ |
45 | | #include "gserrors.h" |
46 | | #include "gxfarith.h" |
47 | | #include "gxfixed.h" |
48 | | #include "stdint_.h" |
49 | | #include "stdio_.h" |
50 | | #include "gp.h" |
51 | | |
52 | | /* ------ Redirected stdout and stderr ------ */ |
53 | | |
54 | | #include <stdarg.h> |
55 | | #define PRINTF_BUF_LENGTH 1024 |
56 | | |
57 | | static const char msg_truncated[] = "\n*** Previous line has been truncated.\n"; |
58 | | |
59 | | int outprintf(const gs_memory_t *mem, const char *fmt, ...) |
60 | 9.06k | { |
61 | 9.06k | int count; |
62 | 9.06k | char buf[PRINTF_BUF_LENGTH]; |
63 | 9.06k | va_list args; |
64 | | |
65 | 9.06k | va_start(args, fmt); |
66 | 9.06k | count = vsnprintf(buf, sizeof(buf), fmt, args); |
67 | 9.06k | if (count < 0 || count >= sizeof(buf)) { /* MSVC || C99 */ |
68 | 0 | outwrite(mem, buf, sizeof(buf) - 1); |
69 | 0 | outwrite(mem, msg_truncated, sizeof(msg_truncated) - 1); |
70 | 9.06k | } else { |
71 | 9.06k | outwrite(mem, buf, count); |
72 | 9.06k | } |
73 | 9.06k | va_end(args); |
74 | 9.06k | return count; |
75 | 9.06k | } |
76 | | |
77 | | int errprintf_nomem(const char *fmt, ...) |
78 | 31.3k | { |
79 | 31.3k | int count; |
80 | 31.3k | char buf[PRINTF_BUF_LENGTH]; |
81 | 31.3k | va_list args; |
82 | 31.3k | gs_memory_t *mem = gp_get_debug_mem_ptr(); |
83 | | |
84 | 31.3k | if (mem == NULL) |
85 | 31.3k | return 0; |
86 | 0 | va_start(args, fmt); |
87 | 0 | count = vsnprintf(buf, sizeof(buf), fmt, args); |
88 | 0 | if (count < 0 || count >= sizeof(buf)) { /* MSVC || C99*/ |
89 | 0 | errwrite(mem, buf, sizeof(buf) - 1); |
90 | 0 | errwrite(mem, msg_truncated, sizeof(msg_truncated) - 1); |
91 | 0 | } else { |
92 | 0 | errwrite(mem, buf, count); |
93 | 0 | } |
94 | 0 | va_end(args); |
95 | 0 | return count; |
96 | 31.3k | } |
97 | | |
98 | | int errprintf(const gs_memory_t *mem, const char *fmt, ...) |
99 | 601k | { |
100 | 601k | int count; |
101 | 601k | char buf[PRINTF_BUF_LENGTH]; |
102 | 601k | va_list args; |
103 | | |
104 | 601k | va_start(args, fmt); |
105 | 601k | count = vsnprintf(buf, sizeof(buf), fmt, args); |
106 | 601k | if (count < 0 || count >= sizeof(buf)) { /* MSVC || C99 */ |
107 | 0 | errwrite(mem, buf, sizeof(buf) - 1); |
108 | 0 | errwrite(mem, msg_truncated, sizeof(msg_truncated) - 1); |
109 | 601k | } else { |
110 | 601k | errwrite(mem, buf, count); |
111 | 601k | } |
112 | 601k | va_end(args); |
113 | 601k | return count; |
114 | 601k | } |
115 | | |
116 | | /* ------ Debugging ------ */ |
117 | | |
118 | | /* We define gs_debug even if DEBUG isn't defined, */ |
119 | | /* so that we can compile individual modules with DEBUG set. */ |
120 | | /* gs_debug is therefore shared between all instances in a multi-instance |
121 | | * setup. This means that {en,dis}abling a debugging flag in one instance |
122 | | * will affect all other instances. */ |
123 | | char gs_debug[128]; |
124 | | |
125 | | /* Test whether a given debugging option is selected. */ |
126 | | /* Some letters automatically imply others. */ |
127 | | bool |
128 | | gs_debug_c(int c) |
129 | 34.8G | { |
130 | 34.8G | bool ret = gs_debug[c]; |
131 | | |
132 | | /* Unroll the first one, to minimise the speed hit */ |
133 | 34.8G | c = gs_debug_flag_implied_by[c]; |
134 | 34.8G | if (c == 0) |
135 | 34.8G | return ret; |
136 | | |
137 | 0 | do { |
138 | 0 | ret |= gs_debug[c]; |
139 | 0 | } while ((c = gs_debug_flag_implied_by[c]) != 0); |
140 | 0 | return ret; |
141 | 34.8G | } |
142 | | |
143 | | /* Define the formats for debugging printout. */ |
144 | | const char *const dprintf_file_and_line_format = "%10s(%4d): "; |
145 | | const char *const dprintf_file_only_format = "%10s(unkn): "; |
146 | | |
147 | | /* |
148 | | * Define the trace printout procedures. We always include these, in case |
149 | | * other modules were compiled with DEBUG set. Note that they must use |
150 | | * out/errprintf, not fprintf nor fput[cs], because of the way that |
151 | | * stdout/stderr are implemented on DLL/shared library builds. |
152 | | */ |
153 | | static const char * |
154 | | dprintf_file_tail(const char *file) |
155 | 0 | { |
156 | 0 | const char *tail = file + strlen(file); |
157 | |
|
158 | 0 | while (tail > file && |
159 | 0 | (isalnum((unsigned char)tail[-1]) || tail[-1] == '.' || tail[-1] == '_') |
160 | 0 | ) |
161 | 0 | --tail; |
162 | 0 | return tail; |
163 | 0 | } |
164 | | void |
165 | | dflush(void) |
166 | 0 | { |
167 | 0 | gs_memory_t *mem = gp_get_debug_mem_ptr(); |
168 | 0 | if (mem) |
169 | 0 | errflush(mem); |
170 | 0 | } |
171 | | #if __LINE__ /* compiler provides it */ |
172 | | void |
173 | | dprintf_file_and_line(const char *file, int line) |
174 | 31.3k | { |
175 | 31.3k | if (gs_debug['/']) |
176 | 0 | dpf(dprintf_file_and_line_format, |
177 | 0 | dprintf_file_tail(file), line); |
178 | 31.3k | } |
179 | | void |
180 | | lprintf_file_and_line(const char *file, int line) |
181 | 0 | { |
182 | 0 | epf("%s(%d): ", file, line); |
183 | 0 | } |
184 | | #else |
185 | | void |
186 | | dprintf_file_only(const char *file) |
187 | | { |
188 | | if (gs_debug['/']) |
189 | | dpf(dprintf_file_only_format, dprintf_file_tail(file)); |
190 | | } |
191 | | void |
192 | | lprintf_file_only(gp_file * f, const char *file) |
193 | | { |
194 | | epf("%s(?): ", file); |
195 | | } |
196 | | #endif |
197 | | void |
198 | | eprintf_program_ident(const char *program_name, |
199 | | long revision_number) |
200 | 0 | { |
201 | 0 | if (program_name) { |
202 | 0 | epf((revision_number ? "%s " : "%s"), program_name); |
203 | 0 | if (revision_number) { |
204 | 0 | int major = (int)(revision_number / 1000); |
205 | 0 | int minor = (int)(revision_number - (major * 1000)) / 10; |
206 | 0 | int patch = revision_number % 10; |
207 | |
|
208 | 0 | epf("%d.%02d.%d", major, minor, patch); |
209 | 0 | } |
210 | 0 | epf(": "); |
211 | 0 | } |
212 | 0 | } |
213 | | #if __LINE__ /* compiler provides it */ |
214 | | void |
215 | | dmprintf_file_and_line(const gs_memory_t *mem,const char *file, int line) |
216 | 22.2k | { |
217 | 22.2k | if (gs_debug['/']) |
218 | 0 | dpfm(mem, dprintf_file_and_line_format, |
219 | 0 | dprintf_file_tail(file), line); |
220 | 22.2k | } |
221 | | #else |
222 | | void |
223 | | dmprintf_file_only(const gs_memory_t *mem,const char *file) |
224 | | { |
225 | | if (gs_debug['/']) |
226 | | dpfm(mem, dprintf_file_only_format, dprintf_file_tail(file)); |
227 | | } |
228 | | #endif |
229 | | |
230 | | /* This calculation is also performed for pdfwrite to manufacture the Producer string |
231 | | * in PDF output. The code is in ghostpdl/devices/vector/gdevpdfu.c pdf_store_default_Producer(). |
232 | | * Should we change this calculation both sets of code need to be updated. |
233 | | */ |
234 | | void |
235 | | printf_program_ident(const gs_memory_t *mem, const char *program_name, long revision_number) |
236 | 0 | { |
237 | 0 | if (program_name) |
238 | 0 | outprintf(mem, (revision_number ? "%s " : "%s"), program_name); |
239 | 0 | if (revision_number) { |
240 | 0 | int major = (int)(revision_number / 1000); |
241 | 0 | int minor = (int)(revision_number - (major * 1000)) / 10; |
242 | 0 | int patch = revision_number % 10; |
243 | |
|
244 | 0 | outprintf(mem, "%d.%02d.%d", major, minor, patch); |
245 | 0 | } |
246 | 0 | } |
247 | | void |
248 | | emprintf_program_ident(const gs_memory_t *mem, |
249 | | const char *program_name, |
250 | | long revision_number) |
251 | 77.9k | { |
252 | 77.9k | if (program_name) { |
253 | 77.9k | epfm(mem, (revision_number ? "%s " : "%s"), program_name); |
254 | 77.9k | if (revision_number) { |
255 | 77.9k | int major = (int)(revision_number / 1000); |
256 | 77.9k | int minor = (int)(revision_number - (major * 1000)) / 10; |
257 | 77.9k | int patch = revision_number % 10; |
258 | | |
259 | 77.9k | epfm(mem, "%d.%02d.%d", major, minor, patch); |
260 | 77.9k | } |
261 | 77.9k | epfm(mem, ": "); |
262 | 77.9k | } |
263 | 77.9k | } |
264 | | #if __LINE__ /* compiler provides it */ |
265 | | void |
266 | | mlprintf_file_and_line(const gs_memory_t *mem, const char *file, int line) |
267 | 0 | { |
268 | 0 | epfm(mem, "%s(%d): ", file, line); |
269 | 0 | } |
270 | | #else |
271 | | void |
272 | | mlprintf_file_only(const gs_memory_t *mem, gp_file * f, const char *file) |
273 | | { |
274 | | epfm(mem, "%s(?): ", file); |
275 | | } |
276 | | #endif |
277 | | |
278 | | /* Log an error return. We always include this, in case other */ |
279 | | /* modules were compiled with DEBUG set. */ |
280 | | #undef gs_log_error /* in case DEBUG isn't set */ |
281 | | int |
282 | | gs_log_error(int err, const char *file, int line) |
283 | 170 | { |
284 | 170 | if (gs_log_errors) { |
285 | 0 | if (file == NULL) |
286 | 0 | dprintf1("Returning error %d.\n", err); |
287 | 0 | else |
288 | 0 | dprintf3("%s(%d): Returning error %d.\n", |
289 | 0 | (const char *)file, line, err); |
290 | 0 | } |
291 | 170 | return err; |
292 | 170 | } |
293 | | |
294 | | /* Check for interrupts before a return. */ |
295 | | int |
296 | | gs_return_check_interrupt(const gs_memory_t *mem, int code) |
297 | 0 | { |
298 | 0 | if (code < 0) |
299 | 0 | return code; |
300 | 0 | { |
301 | 0 | int icode = gp_check_interrupts(mem); |
302 | |
|
303 | 0 | return (icode == 0 ? code : |
304 | 0 | gs_note_error((icode > 0 ? gs_error_interrupt : icode))); |
305 | 0 | } |
306 | 0 | } |
307 | | |
308 | | int gs_throw_imp(const char *func, const char *file, int line, int op, int code, const char *fmt, ...) |
309 | 84.7k | { |
310 | 84.7k | char msg[1024]; |
311 | 84.7k | va_list ap; |
312 | 84.7k | int count; |
313 | 84.7k | gs_memory_t *mem = gp_get_debug_mem_ptr(); |
314 | | |
315 | 84.7k | if (mem == NULL) |
316 | 84.7k | return code; |
317 | | |
318 | 0 | va_start(ap, fmt); |
319 | 0 | count = vsnprintf(msg, sizeof(msg), fmt, ap); |
320 | 0 | msg[sizeof(msg) - 1] = 0; |
321 | 0 | va_end(ap); |
322 | |
|
323 | 0 | if (!gs_debug_c('#')) { |
324 | 0 | ; /* NB: gs_log_errors |
325 | | * we could disable these printfs, and probably will when, |
326 | | * the code becomes more stable: |
327 | | * return code; |
328 | | */ |
329 | 0 | } |
330 | | |
331 | | /* throw */ |
332 | 0 | if (op == 0) |
333 | 0 | errprintf(mem, "+ %s:%d: %s(): %s\n", file, line, func, msg); |
334 | | |
335 | | /* rethrow */ |
336 | 0 | if (op == 1) |
337 | 0 | errprintf(mem, "| %s:%d: %s(): %s\n", file, line, func, msg); |
338 | | |
339 | | /* catch */ |
340 | 0 | if (op == 2) |
341 | 0 | errprintf(mem, "- %s:%d: %s(): %s\n", file, line, func, msg); |
342 | | |
343 | | /* warn */ |
344 | 0 | if (op == 3) |
345 | 0 | errprintf(mem, " %s:%d: %s(): %s\n", file, line, func, msg); |
346 | |
|
347 | 0 | if (count < 0 || count >= sizeof(msg)) { /* MSVC || C99 */ |
348 | 0 | errwrite(mem, msg_truncated, sizeof(msg_truncated) - 1); |
349 | 0 | } |
350 | 0 | return code; |
351 | 84.7k | } |
352 | | |
353 | | const char *gs_errstr(int code) |
354 | 0 | { |
355 | 0 | switch (code) { |
356 | 0 | default: |
357 | 0 | case gs_error_unknownerror: return "unknownerror"; |
358 | 0 | case gs_error_interrupt: return "interrupt"; |
359 | 0 | case gs_error_invalidaccess: return "invalidaccess"; |
360 | 0 | case gs_error_invalidfileaccess: return "invalidfileaccess"; |
361 | 0 | case gs_error_invalidfont: return "invalidfont"; |
362 | 0 | case gs_error_ioerror: return "ioerror"; |
363 | 0 | case gs_error_limitcheck: return "limitcheck"; |
364 | 0 | case gs_error_nocurrentpoint: return "nocurrentpoint"; |
365 | 0 | case gs_error_rangecheck: return "rangecheck"; |
366 | 0 | case gs_error_typecheck: return "typecheck"; |
367 | 0 | case gs_error_undefined: return "undefined"; |
368 | 0 | case gs_error_undefinedfilename: return "undefinedfilename"; |
369 | 0 | case gs_error_undefinedresult: return "undefinedresult"; |
370 | 0 | case gs_error_VMerror: return "vmerror"; |
371 | 0 | case gs_error_unregistered: return "unregistered"; |
372 | 0 | case gs_error_hit_detected: return "hit_detected"; |
373 | 0 | case gs_error_Fatal: return "Fatal"; |
374 | 0 | } |
375 | 0 | } |
376 | | |
377 | | /* ------ Substitutes for missing C library functions ------ */ |
378 | | |
379 | | #ifdef MEMORY__NEED_MEMMOVE /* see memory_.h */ |
380 | | /* Copy bytes like memcpy, guaranteed to handle overlap correctly. */ |
381 | | /* ANSI C defines the returned value as being the src argument, */ |
382 | | /* but with the const restriction removed! */ |
383 | | void * |
384 | | gs_memmove(void *dest, const void *src, size_t len) |
385 | | { |
386 | | if (!len) |
387 | | return (void *)src; |
388 | | #define bdest ((byte *)dest) |
389 | | #define bsrc ((const byte *)src) |
390 | | /* We use len-1 for comparisons because adding len */ |
391 | | /* might produce an offset overflow on segmented systems. */ |
392 | | if (PTR_LE(bdest, bsrc)) { |
393 | | register byte *end = bdest + (len - 1); |
394 | | |
395 | | if (PTR_LE(bsrc, end)) { |
396 | | /* Source overlaps destination from above. */ |
397 | | register const byte *from = bsrc; |
398 | | register byte *to = bdest; |
399 | | |
400 | | for (;;) { |
401 | | *to = *from; |
402 | | if (to >= end) /* faster than = */ |
403 | | return (void *)src; |
404 | | to++; |
405 | | from++; |
406 | | } |
407 | | } |
408 | | } else { |
409 | | register const byte *from = bsrc + (len - 1); |
410 | | |
411 | | if (PTR_LE(bdest, from)) { |
412 | | /* Source overlaps destination from below. */ |
413 | | register const byte *end = bsrc; |
414 | | register byte *to = bdest + (len - 1); |
415 | | |
416 | | for (;;) { |
417 | | *to = *from; |
418 | | if (from <= end) /* faster than = */ |
419 | | return (void *)src; |
420 | | to--; |
421 | | from--; |
422 | | } |
423 | | } |
424 | | } |
425 | | #undef bdest |
426 | | #undef bsrc |
427 | | /* No overlap, it's safe to use memcpy. */ |
428 | | memcpy(dest, src, len); |
429 | | return (void *)src; |
430 | | } |
431 | | #endif |
432 | | |
433 | | #ifdef MEMORY__NEED_MEMCPY /* see memory_.h */ |
434 | | void * |
435 | | gs_memcpy(void *dest, const void *src, size_t len) |
436 | | { |
437 | | if (len > 0) { |
438 | | #define bdest ((byte *)dest) |
439 | | #define bsrc ((const byte *)src) |
440 | | /* We can optimize this much better later on. */ |
441 | | register byte *end = bdest + (len - 1); |
442 | | register const byte *from = bsrc; |
443 | | register byte *to = bdest; |
444 | | |
445 | | for (;;) { |
446 | | *to = *from; |
447 | | if (to >= end) /* faster than = */ |
448 | | break; |
449 | | to++; |
450 | | from++; |
451 | | } |
452 | | } |
453 | | #undef bdest |
454 | | #undef bsrc |
455 | | return (void *)src; |
456 | | } |
457 | | #endif |
458 | | |
459 | | #ifdef MEMORY__NEED_MEMCHR /* see memory_.h */ |
460 | | /* ch should obviously be char rather than int, */ |
461 | | /* but the ANSI standard declaration uses int. */ |
462 | | void * |
463 | | gs_memchr(const void *ptr, int ch, size_t len) |
464 | | { |
465 | | if (len > 0) { |
466 | | register const char *p = ptr; |
467 | | register uint count = len; |
468 | | |
469 | | do { |
470 | | if (*p == (char)ch) |
471 | | return (void *)p; |
472 | | p++; |
473 | | } while (--count); |
474 | | } |
475 | | return 0; |
476 | | } |
477 | | #endif |
478 | | |
479 | | #ifdef MEMORY__NEED_MEMSET /* see memory_.h */ |
480 | | /* ch should obviously be char rather than int, */ |
481 | | /* but the ANSI standard declaration uses int. */ |
482 | | void * |
483 | | gs_memset(void *dest, register int ch, size_t len) |
484 | | { |
485 | | /* |
486 | | * This procedure is used a lot to fill large regions of images, |
487 | | * so we take some trouble to optimize it. |
488 | | */ |
489 | | register char *p = dest; |
490 | | register size_t count = len; |
491 | | |
492 | | ch &= 255; |
493 | | if (len >= sizeof(long) * 3) { |
494 | | long wd = (ch << 24) | (ch << 16) | (ch << 8) | ch; |
495 | | |
496 | | while (ALIGNMENT_MOD(p, sizeof(long))) |
497 | | *p++ = (char)ch, --count; |
498 | | for (; count >= sizeof(long) * 4; |
499 | | p += sizeof(long) * 4, count -= sizeof(long) * 4 |
500 | | ) |
501 | | ((long *)p)[3] = ((long *)p)[2] = ((long *)p)[1] = |
502 | | ((long *)p)[0] = wd; |
503 | | switch (count >> ARCH_LOG2_SIZEOF_LONG) { |
504 | | case 3: |
505 | | *((long *)p) = wd; p += sizeof(long); |
506 | | case 2: |
507 | | *((long *)p) = wd; p += sizeof(long); |
508 | | case 1: |
509 | | *((long *)p) = wd; p += sizeof(long); |
510 | | count &= sizeof(long) - 1; |
511 | | case 0: |
512 | | default: /* can't happen */ |
513 | | DO_NOTHING; |
514 | | } |
515 | | } |
516 | | /* Do any leftover bytes. */ |
517 | | for (; count > 0; --count) |
518 | | *p++ = (char)ch; |
519 | | return dest; |
520 | | } |
521 | | #endif |
522 | | |
523 | | #ifdef malloc__need_realloc /* see malloc_.h */ |
524 | | /* Some systems have non-working implementations of realloc. */ |
525 | | void * |
526 | | gs_realloc(void *old_ptr, size_t old_size, size_t new_size) |
527 | 701k | { |
528 | 701k | void *new_ptr; |
529 | | |
530 | 701k | if (new_size) { |
531 | 701k | new_ptr = malloc(new_size); |
532 | 701k | if (new_ptr == NULL) |
533 | 0 | return NULL; |
534 | 701k | } else |
535 | 0 | new_ptr = NULL; |
536 | | /* We have to pass in the old size, since we have no way to */ |
537 | | /* determine it otherwise. */ |
538 | 701k | if (old_ptr != NULL) { |
539 | 701k | if (new_ptr != NULL) |
540 | 701k | memcpy(new_ptr, old_ptr, min(old_size, new_size)); |
541 | 701k | free(old_ptr); |
542 | 701k | } |
543 | 701k | return new_ptr; |
544 | 701k | } |
545 | | #endif |
546 | | |
547 | | /* ------ Debugging support ------ */ |
548 | | |
549 | | #ifdef DEBUG |
550 | | /* Print a string in hexdump format. */ |
551 | | void |
552 | | debug_print_string_hex_nomem(const byte * chrs, uint len) |
553 | | { |
554 | | uint i; |
555 | | |
556 | | for (i = 0; i < len; i++) |
557 | | dprintf1("%02x", chrs[i]); |
558 | | dflush(); |
559 | | } |
560 | | #endif |
561 | | |
562 | | /* Dump a region of memory. */ |
563 | | void |
564 | | debug_dump_bytes(const gs_memory_t *mem, const byte * from, const byte * to, const char *msg) |
565 | 0 | { |
566 | 0 | const byte *p = from; |
567 | |
|
568 | 0 | if (from < to && msg) |
569 | 0 | dmprintf1(mem, "%s:\n", msg); |
570 | 0 | while (p != to) { |
571 | 0 | const byte *q = min(p + 16, to); |
572 | |
|
573 | 0 | dmprintf1(mem, PRI_INTPTR, (intptr_t)p); |
574 | 0 | while (p != q) |
575 | 0 | dmprintf1(mem, " %02x", *p++); |
576 | 0 | dmputc(mem, '\n'); |
577 | 0 | } |
578 | 0 | } |
579 | | |
580 | | /* Dump a bitmap. */ |
581 | | void |
582 | | debug_dump_bitmap(const gs_memory_t *mem, const byte * bits, uint raster, uint height, const char *msg) |
583 | 0 | { |
584 | 0 | uint y; |
585 | 0 | const byte *data = bits; |
586 | |
|
587 | 0 | for (y = 0; y < height; ++y, data += raster) |
588 | 0 | debug_dump_bytes(mem, data, data + raster, (y == 0 ? msg : NULL)); |
589 | 0 | } |
590 | | |
591 | | /* Print a string. */ |
592 | | void |
593 | | debug_print_string(const gs_memory_t *mem, const byte * chrs, uint len) |
594 | 0 | { |
595 | 0 | uint i; |
596 | |
|
597 | 0 | for (i = 0; i < len; i++) |
598 | 0 | dmputc(mem, chrs[i]); |
599 | 0 | dmflush(mem); |
600 | 0 | } |
601 | | |
602 | | /* Print a string in hexdump format. */ |
603 | | void |
604 | | debug_print_string_hex(const gs_memory_t *mem, const byte * chrs, uint len) |
605 | 0 | { |
606 | 0 | uint i; |
607 | |
|
608 | 0 | for (i = 0; i < len; i++) |
609 | 0 | dmprintf1(mem, "%02x", chrs[i]); |
610 | 0 | dmflush(mem); |
611 | 0 | } |
612 | | |
613 | | /* |
614 | | * The following code prints a hex stack backtrace on Linux/Intel systems. |
615 | | * It is here to be patched into places where we need to print such a trace |
616 | | * because of gdb's inability to put breakpoints in dynamically created |
617 | | * threads. |
618 | | * |
619 | | * first_arg is the first argument of the procedure into which this code |
620 | | * is patched. |
621 | | */ |
622 | | #ifdef DEBUG |
623 | | #define BACKTRACE(first_arg)\ |
624 | | BEGIN\ |
625 | | ulong *fp_ = (ulong *)&first_arg - 2;\ |
626 | | for (; fp_ && (fp_[1] & 0xff000000) == 0x08000000; fp_ = (ulong *)*fp_)\ |
627 | | dprintf2(" fp="PRI_INTPTR" ip=0x%lx\n", (intptr_t)fp_, fp_[1]);\ |
628 | | END |
629 | | #endif |
630 | | |
631 | | /* ------ Arithmetic ------ */ |
632 | | |
633 | | /* Compute M modulo N. Requires N > 0; guarantees 0 <= imod(M,N) < N, */ |
634 | | /* regardless of the whims of the % operator for negative operands. */ |
635 | | int |
636 | | imod(int m, int n) |
637 | 617M | { |
638 | 617M | if (n <= 0) |
639 | 2 | return 0; /* sanity check */ |
640 | 617M | if (m >= 0) |
641 | 602M | return m % n; |
642 | 14.9M | { |
643 | 14.9M | int r = -m % n; |
644 | | |
645 | 14.9M | return (r == 0 ? 0 : n - r); |
646 | 617M | } |
647 | 617M | } |
648 | | |
649 | | /* Compute the GCD of two integers. */ |
650 | | int |
651 | | igcd(int x, int y) |
652 | 29.4M | { |
653 | 29.4M | int c = x, d = y; |
654 | | |
655 | 29.4M | if (c < 0) |
656 | 0 | c = -c; |
657 | 29.4M | if (d < 0) |
658 | 0 | d = -d; |
659 | 62.2M | while (c != 0 && d != 0) |
660 | 32.7M | if (c > d) |
661 | 9.61M | c %= d; |
662 | 23.1M | else |
663 | 23.1M | d %= c; |
664 | 29.4M | return d + c; /* at most one is non-zero */ |
665 | 29.4M | } |
666 | | |
667 | | /* Compute X such that A*X = B mod M. See gxarith.h for details. */ |
668 | | int |
669 | | idivmod(int a, int b, int m) |
670 | 0 | { |
671 | | /* |
672 | | * Use the approach indicated in Knuth vol. 2, section 4.5.2, Algorithm |
673 | | * X (p. 302) and exercise 15 (p. 315, solution p. 523). |
674 | | */ |
675 | 0 | int u1 = 0, u3 = m; |
676 | 0 | int v1 = 1, v3 = a; |
677 | | /* |
678 | | * The following loop will terminate with a * u1 = gcd(a, m) mod m. |
679 | | * Then x = u1 * b / gcd(a, m) mod m. Since we require that |
680 | | * gcd(a, m) | gcd(a, b), it follows that gcd(a, m) | b, so the |
681 | | * division is exact. |
682 | | */ |
683 | 0 | while (v3) { |
684 | 0 | int q = u3 / v3, t; |
685 | |
|
686 | 0 | t = u1 - v1 * q, u1 = v1, v1 = t; |
687 | 0 | t = u3 - v3 * q, u3 = v3, v3 = t; |
688 | 0 | } |
689 | 0 | return imod(u1 * b / igcd(a, m), m); |
690 | 0 | } |
691 | | |
692 | | /* Compute floor(log2(N)). Requires N > 0. */ |
693 | | int |
694 | | ilog2(int n) |
695 | 48.0M | { |
696 | 48.0M | int m = n, l = 0; |
697 | | |
698 | 78.0M | while (m >= 16) |
699 | 29.9M | m >>= 4, l += 4; |
700 | 48.0M | return |
701 | 48.0M | (m <= 1 ? l : |
702 | 48.0M | "\000\000\001\001\002\002\002\002\003\003\003\003\003\003\003\003"[m] + l); |
703 | 48.0M | } |
704 | | |
705 | | /* |
706 | | * Compute A * B / C when 0 <= B < C and A * B exceeds (or might exceed) |
707 | | * the capacity of a long. |
708 | | * Note that this procedure takes the floor, rather than truncating |
709 | | * towards zero, if A < 0. This ensures that 0 <= R < C. |
710 | | */ |
711 | | |
712 | | #define num_bits (sizeof(fixed) * 8) |
713 | | #define half_bits (num_bits / 2) |
714 | | #define half_mask ((1L << half_bits) - 1) |
715 | | |
716 | | /* |
717 | | * If doubles aren't wide enough, we lose too much precision by using double |
718 | | * arithmetic: we have to use the slower, accurate fixed-point algorithm. |
719 | | * See the simpler implementation below for more information. |
720 | | */ |
721 | | #define MAX_OTHER_FACTOR_BITS\ |
722 | 83.2M | (ARCH_DOUBLE_MANTISSA_BITS - ARCH_SIZEOF_FIXED * 8) |
723 | | #define ROUND_BITS\ |
724 | 945k | (ARCH_SIZEOF_FIXED * 8 * 2 - ARCH_DOUBLE_MANTISSA_BITS) |
725 | | |
726 | | #if ROUND_BITS >= MAX_OTHER_FACTOR_BITS - 1 |
727 | | |
728 | | #ifdef DEBUG |
729 | | struct { |
730 | | long mnanb, mnab, manb, mab, mnc, mdq, mde, mds, mqh, mql; |
731 | | } fmq_stat; |
732 | | # define mincr(x) ++fmq_stat.x |
733 | | #else |
734 | | # define mincr(x) DO_NOTHING |
735 | | #endif |
736 | | fixed |
737 | | fixed_mult_quo(fixed signed_A, fixed B, fixed C) |
738 | | { |
739 | | /* First compute A * B in double-fixed precision. */ |
740 | | ulong A = (signed_A < 0 ? -signed_A : signed_A); |
741 | | long msw; |
742 | | ulong lsw; |
743 | | ulong p1; |
744 | | |
745 | | if (B <= half_mask) { |
746 | | if (A <= half_mask) { |
747 | | ulong P = A * B; |
748 | | fixed Q = P / (ulong)C; |
749 | | |
750 | | mincr(mnanb); |
751 | | /* If A < 0 and the division isn't exact, take the floor. */ |
752 | | return (signed_A >= 0 ? Q : Q * C == P ? -Q : ~Q /* -Q - 1 */); |
753 | | } |
754 | | /* |
755 | | * We might still have C <= half_mask, which we can |
756 | | * handle with a simpler algorithm. |
757 | | */ |
758 | | lsw = (A & half_mask) * B; |
759 | | p1 = (A >> half_bits) * B; |
760 | | if (C <= half_mask) { |
761 | | fixed q0 = (p1 += lsw >> half_bits) / C; |
762 | | ulong rem = ((p1 - C * q0) << half_bits) + (lsw & half_mask); |
763 | | ulong q1 = rem / (ulong)C; |
764 | | fixed Q = (q0 << half_bits) + q1; |
765 | | |
766 | | mincr(mnc); |
767 | | /* If A < 0 and the division isn't exact, take the floor. */ |
768 | | return (signed_A >= 0 ? Q : q1 * C == rem ? -Q : ~Q); |
769 | | } |
770 | | msw = p1 >> half_bits; |
771 | | mincr(manb); |
772 | | } else if (A <= half_mask) { |
773 | | p1 = A * (B >> half_bits); |
774 | | msw = p1 >> half_bits; |
775 | | lsw = A * (B & half_mask); |
776 | | mincr(mnab); |
777 | | } else { /* We have to compute all 4 products. :-( */ |
778 | | ulong lo_A = A & half_mask; |
779 | | ulong hi_A = A >> half_bits; |
780 | | ulong lo_B = B & half_mask; |
781 | | ulong hi_B = B >> half_bits; |
782 | | ulong p1x = hi_A * lo_B; |
783 | | |
784 | | msw = hi_A * hi_B; |
785 | | lsw = lo_A * lo_B; |
786 | | p1 = lo_A * hi_B; |
787 | | if (p1 > max_ulong - p1x) |
788 | | msw += 1L << half_bits; |
789 | | p1 += p1x; |
790 | | msw += p1 >> half_bits; |
791 | | mincr(mab); |
792 | | } |
793 | | /* Finish up by adding the low half of p1 to the high half of lsw. */ |
794 | | #if max_fixed < max_long |
795 | | p1 &= half_mask; |
796 | | #endif |
797 | | p1 <<= half_bits; |
798 | | if (p1 > max_ulong - lsw) |
799 | | msw++; |
800 | | lsw += p1; |
801 | | /* |
802 | | * Now divide the double-length product by C. Note that we know msw |
803 | | * < C (otherwise the quotient would overflow). Start by shifting |
804 | | * (msw,lsw) and C left until C >= 1 << (num_bits - 1). |
805 | | */ |
806 | | { |
807 | | ulong denom = C; |
808 | | int shift = 0; |
809 | | |
810 | | #define bits_4th (num_bits / 4) |
811 | | if (denom < 1L << (num_bits - bits_4th)) { |
812 | | mincr(mdq); |
813 | | denom <<= bits_4th, shift += bits_4th; |
814 | | } |
815 | | #undef bits_4th |
816 | | #define bits_8th (num_bits / 8) |
817 | | if (denom < 1L << (num_bits - bits_8th)) { |
818 | | mincr(mde); |
819 | | denom <<= bits_8th, shift += bits_8th; |
820 | | } |
821 | | #undef bits_8th |
822 | | while (!(denom & (-1L << (num_bits - 1)))) { |
823 | | mincr(mds); |
824 | | denom <<= 1, ++shift; |
825 | | } |
826 | | msw = (msw << shift) + (lsw >> (num_bits - shift)); |
827 | | lsw <<= shift; |
828 | | #if max_fixed < max_long |
829 | | lsw &= (1L << (sizeof(fixed) * 8)) - 1; |
830 | | #endif |
831 | | /* Compute a trial upper-half quotient. */ |
832 | | { |
833 | | ulong hi_D = denom >> half_bits; |
834 | | ulong lo_D = denom & half_mask; |
835 | | ulong hi_Q = (ulong) msw / hi_D; |
836 | | |
837 | | /* hi_Q might be too high by 1 or 2, but it isn't too low. */ |
838 | | ulong p0 = hi_Q * hi_D; |
839 | | ulong p1 = hi_Q * lo_D; |
840 | | ulong hi_P; |
841 | | |
842 | | while ((hi_P = p0 + (p1 >> half_bits)) > msw || |
843 | | (hi_P == msw && ((p1 & half_mask) << half_bits) > lsw) |
844 | | ) { /* hi_Q was too high by 1. */ |
845 | | --hi_Q; |
846 | | p0 -= hi_D; |
847 | | p1 -= lo_D; |
848 | | mincr(mqh); |
849 | | } |
850 | | p1 = (p1 & half_mask) << half_bits; |
851 | | if (p1 > lsw) |
852 | | msw--; |
853 | | lsw -= p1; |
854 | | msw -= hi_P; |
855 | | /* Now repeat to get the lower-half quotient. */ |
856 | | msw = (msw << half_bits) + (lsw >> half_bits); |
857 | | #if max_fixed < max_long |
858 | | lsw &= half_mask; |
859 | | #endif |
860 | | lsw <<= half_bits; |
861 | | { |
862 | | ulong lo_Q = (ulong) msw / hi_D; |
863 | | long Q; |
864 | | |
865 | | p1 = lo_Q * lo_D; |
866 | | p0 = lo_Q * hi_D; |
867 | | while ((hi_P = p0 + (p1 >> half_bits)) > msw || |
868 | | (hi_P == msw && ((p1 & half_mask) << half_bits) > lsw) |
869 | | ) { /* lo_Q was too high by 1. */ |
870 | | --lo_Q; |
871 | | p0 -= hi_D; |
872 | | p1 -= lo_D; |
873 | | mincr(mql); |
874 | | } |
875 | | Q = (hi_Q << half_bits) + lo_Q; |
876 | | return (signed_A >= 0 ? Q : p0 | p1 ? ~Q /* -Q - 1 */ : -Q); |
877 | | } |
878 | | } |
879 | | } |
880 | | } |
881 | | |
882 | | #else /* use doubles */ |
883 | | |
884 | | /* |
885 | | * Compute A * B / C as above using doubles. If floating point is |
886 | | * reasonably fast, this is much faster than the fixed-point algorithm. |
887 | | */ |
888 | | fixed |
889 | | fixed_mult_quo(fixed signed_A, fixed B, fixed C) |
890 | 81.7M | { |
891 | | /* |
892 | | * Check whether A * B will fit in the mantissa of a double. |
893 | | */ |
894 | 164M | #define MAX_OTHER_FACTOR (1L << MAX_OTHER_FACTOR_BITS) |
895 | 81.7M | if (B < MAX_OTHER_FACTOR || any_abs(signed_A) < MAX_OTHER_FACTOR) { |
896 | 80.7M | #undef MAX_OTHER_FACTOR |
897 | | /* |
898 | | * The product fits, so a straightforward double computation |
899 | | * will be exact. |
900 | | */ |
901 | 80.7M | return (fixed)floor((double)signed_A * B / C); |
902 | 80.7M | } else { |
903 | | /* |
904 | | * The product won't fit. However, the approximate product will |
905 | | * only be off by at most +/- 1/2 * (1 << ROUND_BITS) because of |
906 | | * rounding. If we add 1 << ROUND_BITS to the value of the product |
907 | | * (i.e., 1 in the least significant bit of the mantissa), the |
908 | | * result is always greater than the correct product by between 1/2 |
909 | | * and 3/2 * (1 << ROUND_BITS). We know this is less than C: |
910 | | * because of the 'if' just above, we know that B >= |
911 | | * MAX_OTHER_FACTOR; since B <= C, we know C >= MAX_OTHER_FACTOR; |
912 | | * and because of the #if that chose between the two |
913 | | * implementations, we know that C >= 2 * (1 << ROUND_BITS). Hence, |
914 | | * the quotient after dividing by C will be at most 1 too large. |
915 | | */ |
916 | 945k | fixed q = |
917 | 945k | (fixed)floor(((double)signed_A * B + (1L << ROUND_BITS)) / C); |
918 | | |
919 | | /* |
920 | | * Compute the remainder R. If the quotient was correct, |
921 | | * 0 <= R < C. If the quotient was too high, -C <= R < 0. |
922 | | */ |
923 | 945k | if (signed_A * B - q * C < 0) |
924 | 1.77k | --q; |
925 | 945k | return q; |
926 | 945k | } |
927 | 81.7M | } |
928 | | |
929 | | #endif |
930 | | |
931 | | #undef MAX_OTHER_FACTOR_BITS |
932 | | #undef ROUND_BITS |
933 | | |
934 | | #undef num_bits |
935 | | #undef half_bits |
936 | | #undef half_mask |
937 | | |
938 | | /* Trace calls on sqrt when debugging. */ |
939 | | double |
940 | | gs_sqrt(double x, const char *file, int line) |
941 | 0 | { |
942 | | #ifdef DEBUG |
943 | | if (gs_debug_c('~')) { |
944 | | dprintf3("[~]sqrt(%g) at %s:%d\n", x, (const char *)file, line); |
945 | | dflush(); |
946 | | } |
947 | | #endif |
948 | 0 | return orig_sqrt(x); |
949 | 0 | } |
950 | | |
951 | | static const int isincos[5] = |
952 | | {0, 1, 0, -1, 0}; |
953 | | |
954 | | /* GCC with -ffast-math compiles ang/90. as ang*(1/90.), losing precission. |
955 | | * This doesn't happen when the numeral is replaced with a non-const variable. |
956 | | * So we define the variable to work around the GCC problem. |
957 | | */ |
958 | | double const_90_degrees = 90.; |
959 | | |
960 | | double |
961 | | gs_sin_degrees(double ang) |
962 | 3.60M | { |
963 | 3.60M | double quot = ang / const_90_degrees; |
964 | | |
965 | 3.60M | if (floor(quot) == quot) { |
966 | | /* |
967 | | * We need 4.0, rather than 4, here because of non-ANSI compilers. |
968 | | * The & 3 is because quot might be negative. |
969 | | */ |
970 | 1.02M | return isincos[(int)fmod(quot, 4.0) & 3]; |
971 | 1.02M | } |
972 | 2.57M | return sin(ang * (M_PI / 180)); |
973 | 3.60M | } |
974 | | |
975 | | double |
976 | | gs_cos_degrees(double ang) |
977 | 58.8M | { |
978 | 58.8M | double quot = ang / const_90_degrees; |
979 | | |
980 | 58.8M | if (floor(quot) == quot) { |
981 | | /* See above re the following line. */ |
982 | 931k | return isincos[((int)fmod(quot, 4.0) & 3) + 1]; |
983 | 931k | } |
984 | 57.9M | return cos(ang * (M_PI / 180)); |
985 | 58.8M | } |
986 | | |
987 | | void |
988 | | gs_sincos_degrees(double ang, gs_sincos_t * psincos) |
989 | 4.57M | { |
990 | 4.57M | double quot = ang / const_90_degrees; |
991 | | |
992 | 4.57M | if (floor(quot) == quot) { |
993 | | /* See above re the following line. */ |
994 | 491k | int quads = (int)fmod(quot, 4.0) & 3; |
995 | | |
996 | 491k | psincos->sin = isincos[quads]; |
997 | 491k | psincos->cos = isincos[quads + 1]; |
998 | 491k | psincos->orthogonal = true; |
999 | 4.08M | } else { |
1000 | 4.08M | double arad = ang * (M_PI / 180); |
1001 | | |
1002 | 4.08M | psincos->sin = sin(arad); |
1003 | 4.08M | psincos->cos = cos(arad); |
1004 | 4.08M | psincos->orthogonal = false; |
1005 | 4.08M | } |
1006 | 4.57M | } |
1007 | | |
1008 | | /* |
1009 | | * Define an atan2 function that returns an angle in degrees and uses |
1010 | | * the PostScript quadrant rules. Note that it may return |
1011 | | * gs_error_undefinedresult. |
1012 | | */ |
1013 | | int |
1014 | | gs_atan2_degrees(double y, double x, double *pangle) |
1015 | 2.61M | { |
1016 | 2.61M | if (y == 0) { /* on X-axis, special case */ |
1017 | 885k | if (x == 0) |
1018 | 170 | return_error(gs_error_undefinedresult); |
1019 | 885k | *pangle = (x < 0 ? 180 : 0); |
1020 | 1.72M | } else { |
1021 | 1.72M | double result = atan2(y, x) * radians_to_degrees; |
1022 | | |
1023 | 1.72M | if (result < 0) |
1024 | 979k | result += 360; |
1025 | 1.72M | *pangle = result; |
1026 | 1.72M | } |
1027 | 2.61M | return 0; |
1028 | 2.61M | } |
1029 | | |
1030 | | /* |
1031 | | * Define a function for finding intersection of small bars. |
1032 | | * Coordinates must be so small that their cubes fit into 60 bits. |
1033 | | * This function doesn't check intersections at end of bars, |
1034 | | * so the caller must care of them on necessity. |
1035 | | * Returns : *ry is the Y-coordinate of the intersection |
1036 | | * truncated to 'fixed'; *ey is 1 iff the precise Y coordinate of |
1037 | | * the intersection is greater than *ry (used by the shading algorithm). |
1038 | | */ |
1039 | | bool |
1040 | | gx_intersect_small_bars(fixed q0x, fixed q0y, fixed q1x, fixed q1y, fixed q2x, fixed q2y, |
1041 | | fixed q3x, fixed q3y, fixed *ry, fixed *ey) |
1042 | 0 | { |
1043 | 0 | fixed dx1 = q1x - q0x, dy1 = q1y - q0y; |
1044 | 0 | fixed dx2 = q2x - q0x, dy2 = q2y - q0y; |
1045 | 0 | fixed dx3 = q3x - q0x, dy3 = q3y - q0y; |
1046 | |
|
1047 | 0 | int64_t vp2a, vp2b, vp3a, vp3b; |
1048 | 0 | int s2, s3; |
1049 | |
|
1050 | 0 | if (dx1 == 0 && dy1 == 0) |
1051 | 0 | return false; /* Zero length bars are out of interest. */ |
1052 | 0 | if (dx2 == 0 && dy2 == 0) |
1053 | 0 | return false; /* Contacting ends are out of interest. */ |
1054 | 0 | if (dx3 == 0 && dy3 == 0) |
1055 | 0 | return false; /* Contacting ends are out of interest. */ |
1056 | 0 | if (dx2 == dx1 && dy2 == dy1) |
1057 | 0 | return false; /* Contacting ends are out of interest. */ |
1058 | 0 | if (dx3 == dx1 && dy3 == dy1) |
1059 | 0 | return false; /* Contacting ends are out of interest. */ |
1060 | 0 | if (dx2 == dx3 && dy2 == dy3) |
1061 | 0 | return false; /* Zero length bars are out of interest. */ |
1062 | 0 | vp2a = (int64_t)dx1 * dy2; |
1063 | 0 | vp2b = (int64_t)dy1 * dx2; |
1064 | | /* vp2 = vp2a - vp2b; It can overflow int64_t, but we only need the sign. */ |
1065 | 0 | if (vp2a > vp2b) |
1066 | 0 | s2 = 1; |
1067 | 0 | else if (vp2a < vp2b) |
1068 | 0 | s2 = -1; |
1069 | 0 | else |
1070 | 0 | s2 = 0; |
1071 | 0 | vp3a = (int64_t)dx1 * dy3; |
1072 | 0 | vp3b = (int64_t)dy1 * dx3; |
1073 | | /* vp3 = vp3a - vp3b; It can overflow int64_t, but we only need the sign. */ |
1074 | 0 | if (vp3a > vp3b) |
1075 | 0 | s3 = 1; |
1076 | 0 | else if (vp3a < vp3b) |
1077 | 0 | s3 = -1; |
1078 | 0 | else |
1079 | 0 | s3 = 0; |
1080 | 0 | if (s2 == 0) { |
1081 | 0 | if (s3 == 0) |
1082 | 0 | return false; /* Collinear bars - out of interest. */ |
1083 | 0 | if (0 <= dx2 && dx2 <= dx1 && 0 <= dy2 && dy2 <= dy1) { |
1084 | | /* The start of the bar 2 is in the bar 1. */ |
1085 | 0 | *ry = q2y; |
1086 | 0 | *ey = 0; |
1087 | 0 | return true; |
1088 | 0 | } |
1089 | 0 | } else if (s3 == 0) { |
1090 | 0 | if (0 <= dx3 && dx3 <= dx1 && 0 <= dy3 && dy3 <= dy1) { |
1091 | | /* The end of the bar 2 is in the bar 1. */ |
1092 | 0 | *ry = q3y; |
1093 | 0 | *ey = 0; |
1094 | 0 | return true; |
1095 | 0 | } |
1096 | 0 | } else if (s2 * s3 < 0) { |
1097 | | /* The intersection definitely exists, so the determinant isn't zero. */ |
1098 | 0 | fixed d23x = dx3 - dx2, d23y = dy3 - dy2; |
1099 | 0 | int64_t det = (int64_t)dx1 * d23y - (int64_t)dy1 * d23x; |
1100 | 0 | int64_t mul = (int64_t)dx2 * d23y - (int64_t)dy2 * d23x; |
1101 | 0 | { |
1102 | | /* Assuming small bars : cubes of coordinates must fit into int64_t. |
1103 | | curve_samples must provide that. */ |
1104 | 0 | int64_t num = dy1 * mul, iiy; |
1105 | 0 | fixed iy; |
1106 | 0 | fixed pry, pey; |
1107 | |
|
1108 | 0 | { /* Likely when called form wedge_trap_decompose or constant_color_quadrangle, |
1109 | | we always have det > 0 && num >= 0, but we check here for a safety reason. */ |
1110 | 0 | if (det < 0) |
1111 | 0 | num = -num, det = -det; |
1112 | 0 | iiy = (num >= 0 ? num / det : (num - det + 1) / det); |
1113 | 0 | iy = (fixed)iiy; |
1114 | 0 | if (iy != iiy) { |
1115 | | /* If it is inside the bars, it must fit into fixed. */ |
1116 | 0 | return false; |
1117 | 0 | } |
1118 | 0 | } |
1119 | 0 | if (dy1 > 0) { |
1120 | 0 | if (iy < 0 || iy >= dy1) |
1121 | 0 | return false; /* Outside the bar 1. */ |
1122 | 0 | } else { |
1123 | 0 | if (iy > 0 || iy <= dy1) |
1124 | 0 | return false; /* Outside the bar 1. */ |
1125 | 0 | } |
1126 | 0 | if (dy2 < dy3) { |
1127 | 0 | if (iy <= dy2 || iy >= dy3) |
1128 | 0 | return false; /* Outside the bar 2. */ |
1129 | 0 | } else { |
1130 | 0 | if (iy >= dy2 || iy <= dy3) |
1131 | 0 | return false; /* Outside the bar 2. */ |
1132 | 0 | } |
1133 | 0 | pry = q0y + (fixed)iy; |
1134 | 0 | pey = (iy * det < num ? 1 : 0); |
1135 | 0 | *ry = pry; |
1136 | 0 | *ey = pey; |
1137 | 0 | } |
1138 | 0 | return true; |
1139 | 0 | } |
1140 | 0 | return false; |
1141 | 0 | } |
1142 | | |
1143 | | /* gs_debug_flags handling code */ |
1144 | | |
1145 | | const gs_debug_flag_details gs_debug_flags[] = |
1146 | | { |
1147 | | #define FLAG(a,b,c,d) {1, # a ,d} |
1148 | | #define UNUSED(a) { 0, "", "" }, |
1149 | | #include "gdbflags.h" |
1150 | | #undef FLAG |
1151 | | #undef UNUSED |
1152 | | }; |
1153 | | |
1154 | | const byte gs_debug_flag_implied_by[] = |
1155 | | { |
1156 | | #define FLAG(a,b,c,d) c |
1157 | | #define UNUSED(a) 0, |
1158 | | #include "gdbflags.h" |
1159 | | #undef FLAG |
1160 | | #undef UNUSED |
1161 | | }; |
1162 | | |
1163 | | int gs_debug_flags_parse(gs_memory_t *heap, const char *arg) |
1164 | 0 | { |
1165 | | #ifdef DEBUG |
1166 | | const char *p; |
1167 | | int i, j; |
1168 | | int result = 0; |
1169 | | |
1170 | | while (*arg != 0) { |
1171 | | /* Skip over any commas */ |
1172 | | byte value = 0xff; |
1173 | | while (*arg == ',') |
1174 | | arg++; |
1175 | | if (*arg == '-') { |
1176 | | value = 0; |
1177 | | arg++; |
1178 | | } |
1179 | | if (*arg == ',') { |
1180 | | arg++; |
1181 | | continue; |
1182 | | } |
1183 | | if (*arg == 0) |
1184 | | return result; |
1185 | | for (i=0; i < gs_debug_flags_max; i++) { |
1186 | | char c, d; |
1187 | | if (!gs_debug_flags[i].used) |
1188 | | continue; |
1189 | | p = arg; |
1190 | | for (j=0; j < sizeof(gs_debug_flags[i].short_desc); j++) { |
1191 | | d = gs_debug_flags[i].short_desc[j]; |
1192 | | c = *p++; |
1193 | | if (d == '_') d = '-'; |
1194 | | if (c == ',') |
1195 | | c = 0; |
1196 | | if ((c != d) || (c == 0)) |
1197 | | break; |
1198 | | } |
1199 | | if ((c == 0) && (d == 0)) |
1200 | | break; |
1201 | | } |
1202 | | if (i < gs_debug_flags_max) |
1203 | | gs_debug[i] = value; |
1204 | | else { |
1205 | | outprintf(heap, "Unknown debug flag: "); |
1206 | | p = arg; |
1207 | | do { |
1208 | | char c = *p++; |
1209 | | if ((c == 0) || (c == ',')) |
1210 | | break; |
1211 | | outprintf(heap, "%c", c); |
1212 | | } while (1); |
1213 | | outprintf(heap, "\n"); |
1214 | | result = gs_error_Fatal; |
1215 | | } |
1216 | | arg = p-1; |
1217 | | } |
1218 | | return result; |
1219 | | #else |
1220 | 0 | outprintf(heap, "Warning: debug flags ignored in release builds\n"); |
1221 | 0 | return 0; |
1222 | 0 | #endif |
1223 | 0 | } |
1224 | | |
1225 | | void |
1226 | | gs_debug_flags_list(gs_memory_t *heap) |
1227 | 0 | { |
1228 | | #ifdef DEBUG |
1229 | | int i, j; |
1230 | | |
1231 | | outprintf(heap, "Debugging flags are as follows:\n\n-Z --debug= Description\n"); |
1232 | | for (i=0; i < gs_debug_flags_max; i++) { |
1233 | | if (!gs_debug_flags[i].used) |
1234 | | continue; |
1235 | | outprintf(heap, " %c ", (i < 32 || i > 126 ? ' ' : i)); |
1236 | | for (j=0; j < sizeof(gs_debug_flags[i].short_desc); j++) { |
1237 | | char c = gs_debug_flags[i].short_desc[j]; |
1238 | | if (c == 0) |
1239 | | break; |
1240 | | if (c == '_') |
1241 | | c = '-'; |
1242 | | outprintf(heap, "%c", c); |
1243 | | } |
1244 | | for (; j < sizeof(gs_debug_flags[i].short_desc); j++) { |
1245 | | outprintf(heap, " "); |
1246 | | } |
1247 | | outprintf(heap, "%s\n", gs_debug_flags[i].long_desc); |
1248 | | } |
1249 | | outprintf(heap, |
1250 | | "\nDebugging may be enabled by using -Zx (where x is one of the 1 character\n" |
1251 | | "codes given above), or by using --debug=xxxxx. Multiple flags may be specified\n" |
1252 | | "at once, using -Zxyz or --debug=xxxxx,yyyyy,zzzzz. -Z=-x or --debug=-xxxxx\n" |
1253 | | "disables a flag once set.\n"); |
1254 | | #else |
1255 | 0 | outprintf(heap, "No debug flags supported in release builds\n"); |
1256 | 0 | #endif |
1257 | 0 | } |
1258 | | |