Bug Summary

File:backend/dvi/mdvi-lib/dviread.c
Warning:line 1091, column 6
Out of bound memory access (accessed memory precedes memory block)

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name dviread.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/rootdir/backend/dvi/mdvi-lib -resource-dir /usr/lib/llvm-16/lib/clang/16 -D HAVE_CONFIG_H -I . -I ../../.. -D PIC -internal-isystem /usr/lib/llvm-16/lib/clang/16/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/13/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir=/rootdir/backend/dvi/mdvi-lib -ferror-limit 19 -fgnuc-version=4.2.1 -analyzer-checker deadcode.DeadStores -analyzer-checker alpha.deadcode.UnreachableCode -analyzer-checker alpha.core.CastSize -analyzer-checker alpha.core.CastToStruct -analyzer-checker alpha.core.IdenticalExpr -analyzer-checker alpha.core.SizeofPtr -analyzer-checker alpha.security.ArrayBoundV2 -analyzer-checker alpha.security.MallocOverflow -analyzer-checker alpha.security.ReturnPtrRange -analyzer-checker alpha.unix.SimpleStream -analyzer-checker alpha.unix.cstring.BufferOverlap -analyzer-checker alpha.unix.cstring.NotNullTerminated -analyzer-checker alpha.unix.cstring.OutOfBounds -analyzer-checker alpha.core.FixedAddr -analyzer-output=html -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /rootdir/html-report/2024-02-18-115154-54189-1 -x c dviread.c
1/*
2 * Copyright (C) 2000, Matias Atria
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18
19#include <config.h>
20#include <stdio.h>
21#include <stdlib.h>
22#include <stdarg.h>
23#include <string.h>
24#include <math.h>
25#include <errno(*__errno_location ()).h>
26#include <unistd.h>
27#include <fcntl.h>
28
29#include "mdvi.h"
30#include "private.h"
31#include "color.h"
32
33typedef int (*DviCommand) __PROTO((DviContext *, int))(DviContext *, int);
34
35#define DVICMDDEF(x)static int x (DviContext *, int) static int x __PROTO((DviContext *, int))(DviContext *, int)
36
37DVICMDDEF(set_char)static int set_char (DviContext *, int);
38DVICMDDEF(set_rule)static int set_rule (DviContext *, int);
39DVICMDDEF(no_op)static int no_op (DviContext *, int);
40DVICMDDEF(push)static int push (DviContext *, int);
41DVICMDDEF(pop)static int pop (DviContext *, int);
42DVICMDDEF(move_right)static int move_right (DviContext *, int);
43DVICMDDEF(move_down)static int move_down (DviContext *, int);
44DVICMDDEF(move_w)static int move_w (DviContext *, int);
45DVICMDDEF(move_x)static int move_x (DviContext *, int);
46DVICMDDEF(move_y)static int move_y (DviContext *, int);
47DVICMDDEF(move_z)static int move_z (DviContext *, int);
48DVICMDDEF(sel_font)static int sel_font (DviContext *, int);
49DVICMDDEF(sel_fontn)static int sel_fontn (DviContext *, int);
50DVICMDDEF(special)static int special (DviContext *, int);
51DVICMDDEF(def_font)static int def_font (DviContext *, int);
52DVICMDDEF(undefined)static int undefined (DviContext *, int);
53DVICMDDEF(unexpected)static int unexpected (DviContext *, int);
54
55static const DviCommand dvi_commands[] = {
56 set_char, set_char, set_char, set_char,
57 set_char, set_char, set_char, set_char,
58 set_char, set_char, set_char, set_char,
59 set_char, set_char, set_char, set_char,
60 set_char, set_char, set_char, set_char,
61 set_char, set_char, set_char, set_char,
62 set_char, set_char, set_char, set_char,
63 set_char, set_char, set_char, set_char,
64 set_char, set_char, set_char, set_char,
65 set_char, set_char, set_char, set_char,
66 set_char, set_char, set_char, set_char,
67 set_char, set_char, set_char, set_char,
68 set_char, set_char, set_char, set_char,
69 set_char, set_char, set_char, set_char,
70 set_char, set_char, set_char, set_char,
71 set_char, set_char, set_char, set_char,
72 set_char, set_char, set_char, set_char,
73 set_char, set_char, set_char, set_char,
74 set_char, set_char, set_char, set_char,
75 set_char, set_char, set_char, set_char,
76 set_char, set_char, set_char, set_char,
77 set_char, set_char, set_char, set_char,
78 set_char, set_char, set_char, set_char,
79 set_char, set_char, set_char, set_char,
80 set_char, set_char, set_char, set_char,
81 set_char, set_char, set_char, set_char,
82 set_char, set_char, set_char, set_char,
83 set_char, set_char, set_char, set_char,
84 set_char, set_char, set_char, set_char,
85 set_char, set_char, set_char, set_char,
86 set_char, set_char, set_char, set_char,
87 set_char, set_char, set_char, set_char, /* 0 - 127 */
88 set_char, set_char, set_char, set_char, /* 128 - 131 */
89 set_rule, /* 132 */
90 set_char, set_char, set_char, set_char, /* 133 - 136 */
91 set_rule, /* 137 */
92 no_op, /* 138 */
93 unexpected, /* 139 (BOP) */
94 unexpected, /* 140 (EOP) */
95 push, /* 141 */
96 pop, /* 142 */
97 move_right, move_right, move_right, move_right, /* 143 - 146 */
98 move_w, move_w, move_w, move_w, move_w, /* 147 - 151 */
99 move_x, move_x, move_x, move_x, move_x, /* 152 - 156 */
100 move_down, move_down, move_down, move_down, /* 157 - 160 */
101 move_y, move_y, move_y, move_y, move_y, /* 161 - 165 */
102 move_z, move_z, move_z, move_z, move_z, /* 166 - 170 */
103 sel_font, sel_font, sel_font, sel_font,
104 sel_font, sel_font, sel_font, sel_font,
105 sel_font, sel_font, sel_font, sel_font,
106 sel_font, sel_font, sel_font, sel_font,
107 sel_font, sel_font, sel_font, sel_font,
108 sel_font, sel_font, sel_font, sel_font,
109 sel_font, sel_font, sel_font, sel_font,
110 sel_font, sel_font, sel_font, sel_font,
111 sel_font, sel_font, sel_font, sel_font,
112 sel_font, sel_font, sel_font, sel_font,
113 sel_font, sel_font, sel_font, sel_font,
114 sel_font, sel_font, sel_font, sel_font,
115 sel_font, sel_font, sel_font, sel_font,
116 sel_font, sel_font, sel_font, sel_font,
117 sel_font, sel_font, sel_font, sel_font,
118 sel_font, sel_font, sel_font, sel_font, /* 171 - 234 */
119 sel_fontn, sel_fontn, sel_fontn, sel_fontn, /* 235 - 238 */
120 special, special, special, special, /* 239 - 242 */
121 def_font, def_font, def_font, def_font, /* 243 - 246 */
122 unexpected, /* 247 (PRE) */
123 unexpected, /* 248 (POST) */
124 unexpected, /* 249 (POST_POST) */
125 undefined, undefined, undefined,
126 undefined, undefined, undefined /* 250 - 255 */
127};
128
129#define DVI_BUFLEN4096 4096
130
131static int mdvi_run_macro(DviContext *dvi, Uchar *macro, size_t len);
132
133static void dummy_draw_glyph(DviContext *dvi, DviFontChar *ch, int x, int y)
134{
135}
136
137static void dummy_draw_rule(DviContext *dvi, int x, int y, Uint w, Uint h, int f)
138{
139}
140
141static int dummy_alloc_colors(void *a, Ulong *b, int c, Ulong d, Ulong e, double f, int g)
142{
143 return -1;
144}
145
146static void *dummy_create_image(void *a, Uint b, Uint c, Uint d)
147{
148 return NULL((void*)0);
149}
150
151static void dummy_free_image(void *a)
152{
153}
154
155static void dummy_dev_destroy(void *a)
156{
157}
158
159static void dummy_dev_putpixel(void *a, int x, int y, Ulong c)
160{
161}
162
163static void dummy_dev_refresh(DviContext *a, void *b)
164{
165}
166
167static void dummy_dev_set_color(void *a, Ulong b, Ulong c)
168{
169}
170
171/* functions to report errors */
172static void dvierr(DviContext *dvi, const char *format, ...)
173{
174 va_list ap;
175
176 va_start(ap, format)__builtin_va_start(ap, format);
177 fprintf(stderrstderr, "%s[%d]: Error: ",
178 dvi->filename, dvi->currpage);
179 vfprintf(stderrstderr, format, ap);
180 va_end(ap)__builtin_va_end(ap);
181}
182
183static void dviwarn(DviContext *dvi, const char *format, ...)
184{
185 va_list ap;
186
187 fprintf(stderrstderr, "%s[%d]: Warning: ",
188 dvi->filename, dvi->currpage);
189 va_start(ap, format)__builtin_va_start(ap, format);
190 vfprintf(stderrstderr, format, ap);
191 va_end(ap)__builtin_va_end(ap);
192}
193
194#define NEEDBYTES(d,n)((d)->buffer.pos + (n) > (d)->buffer.length) \
195 ((d)->buffer.pos + (n) > (d)->buffer.length)
196
197static int get_bytes(DviContext *dvi, size_t n)
198{
199 /*
200 * caller wants to read `n' bytes from dvi->buffer + dvi->pos.
201 * Make sure there is enough data to satisfy the request
202 */
203 if(NEEDBYTES(dvi, n)((dvi)->buffer.pos + (n) > (dvi)->buffer.length)) {
204 size_t required;
205 int newlen;
206
207 if(dvi->buffer.frozen || dvi->in == NULL((void*)0) || feof(dvi->in)) {
208 /* this is EOF */
209 dviwarn(dvi, _("unexpected EOF\n")gettext("unexpected EOF\n"));
210 return -1;
211 }
212 /* get more data */
213 if(dvi->buffer.data == NULL((void*)0)) {
214 /* first allocation */
215 dvi->buffer.size = Max(DVI_BUFLEN, n)(((4096) > (n)) ? (4096) : (n));
216 dvi->buffer.data = (Uchar *)mdvi_malloc(dvi->buffer.size);
217 dvi->buffer.length = 0;
218 dvi->buffer.frozen = 0;
219 } else if(dvi->buffer.pos < dvi->buffer.length) {
220 /* move whatever we want to keep */
221 dvi->buffer.length -= dvi->buffer.pos;
222 memmove(dvi->buffer.data,
223 dvi->buffer.data + dvi->buffer.pos,
224 dvi->buffer.length);
225 } else {
226 /* we can discard all the data in this buffer */
227 dvi->buffer.length = 0;
228 }
229
230 required = n - dvi->buffer.length;
231 if(required > dvi->buffer.size - dvi->buffer.length) {
232 /* need to allocate more memory */
233 dvi->buffer.size = dvi->buffer.length + required + 128;
234 dvi->buffer.data = (Uchar *)xresize(dvi->buffer.data,(char *)mdvi_realloc((dvi->buffer.data), (dvi->buffer.size
) * sizeof(char))
235 char, dvi->buffer.size)(char *)mdvi_realloc((dvi->buffer.data), (dvi->buffer.size
) * sizeof(char))
;
236 }
237 /* now read into the buffer */
238 newlen = fread(dvi->buffer.data + dvi->buffer.length,
239 1, dvi->buffer.size - dvi->buffer.length, dvi->in);
240 if(newlen == -1) {
241 mdvi_error("%s: %s\n", dvi->filename, strerror(errno(*__errno_location ())));
242 return -1;
243 }
244 dvi->buffer.length += newlen;
245 dvi->buffer.pos = 0;
246 }
247 return 0;
248}
249
250/* only relative forward seeks are supported by this function */
251static int dskip(DviContext *dvi, long offset)
252{
253 ASSERT(offset > 0)do { if(!(offset > 0)) mdvi_crash("%s:%d: Assertion %s failed\n"
, "dviread.c", 253, "offset > 0"); } while(0)
;
254
255 if(NEEDBYTES(dvi, offset)((dvi)->buffer.pos + (offset) > (dvi)->buffer.length
)
&& get_bytes(dvi, offset) == -1)
256 return -1;
257 dvi->buffer.pos += offset;
258 return 0;
259}
260
261/* DVI I/O functions (note: here `n' must be <= 4) */
262static long dsgetn(DviContext *dvi, size_t n)
263{
264 long val;
265
266 if(NEEDBYTES(dvi, n)((dvi)->buffer.pos + (n) > (dvi)->buffer.length) && get_bytes(dvi, n) == -1)
267 return -1;
268 val = msgetn(dvi->buffer.data + dvi->buffer.pos, n);
269 dvi->buffer.pos += n;
270 return val;
271}
272
273static int dread(DviContext *dvi, char *buffer, size_t len)
274{
275 if(NEEDBYTES(dvi, len)((dvi)->buffer.pos + (len) > (dvi)->buffer.length) && get_bytes(dvi, len) == -1)
276 return -1;
277 memcpy(buffer, dvi->buffer.data + dvi->buffer.pos, len)bcopy ((dvi->buffer.data + dvi->buffer.pos), (buffer), (
len))
;
278 dvi->buffer.pos += len;
279 return 0;
280}
281
282static long dugetn(DviContext *dvi, size_t n)
283{
284 long val;
285
286 if(NEEDBYTES(dvi, n)((dvi)->buffer.pos + (n) > (dvi)->buffer.length) && get_bytes(dvi, n) == -1)
287 return -1;
288 val = mugetn(dvi->buffer.data + dvi->buffer.pos, n);
289 dvi->buffer.pos += n;
290 return val;
291}
292
293static long dtell(DviContext *dvi)
294{
295 return dvi->depth ?
296 dvi->buffer.pos :
297 ftell(dvi->in) - dvi->buffer.length + dvi->buffer.pos;
298}
299
300static void dreset(DviContext *dvi)
301{
302 if(!dvi->buffer.frozen && dvi->buffer.data)
303 mdvi_free(dvi->buffer.data);
304 dvi->buffer.data = NULL((void*)0);
305 dvi->buffer.size = 0;
306 dvi->buffer.length = 0;
307 dvi->buffer.pos = 0;
308}
309
310#define dsget1(d)dsgetn((d), 1) dsgetn((d), 1)
311#define dsget2(d)dsgetn((d), 2) dsgetn((d), 2)
312#define dsget3(d)dsgetn((d), 3) dsgetn((d), 3)
313#define dsget4(d)dsgetn((d), 4) dsgetn((d), 4)
314#define duget1(d)dugetn((d), 1) dugetn((d), 1)
315#define duget2(d)dugetn((d), 2) dugetn((d), 2)
316#define duget3(d)dugetn((d), 3) dugetn((d), 3)
317#define duget4(d)dugetn((d), 4) dugetn((d), 4)
318
319#ifndef NODEBUG
320static void dviprint(DviContext *dvi, const char *command, int sub, const char *fmt, ...)
321{
322 int i;
323 va_list ap;
324
325 printf("%s: ", dvi->filename);
326 for(i = 0; i < dvi->depth; i++)
327 printf(" ");
328 printf("%4lu: %s", dtell(dvi), command);
329 if(sub >= 0) printf("%d", sub);
330 if(*fmt) printf(": ");
331 va_start(ap, fmt)__builtin_va_start(ap, fmt);
332 vprintf(fmt, ap);
333 va_end(ap)__builtin_va_end(ap);
334}
335#define SHOWCMD(x)if(_mdvi_debug_mask & (1 << 0)) do { dviprint x; } while
(0)
\
336 if(_mdvi_debug_mask & DBG_OPCODE(1 << 0)) do { dviprint x; } while(0)
337#else
338#define SHOWCMD(x)if(_mdvi_debug_mask & (1 << 0)) do { dviprint x; } while
(0)
do { } while(0)
339#endif
340
341int mdvi_find_tex_page(DviContext *dvi, int tex_page)
342{
343 int i;
344
345 for(i = 0; i < dvi->npages; i++)
346 if(dvi->pagemap[i][1] == tex_page)
347 return i;
348 return -1;
349}
350
351/* page sorting functions */
352static int sort_up(const void *p1, const void *p2)
353{
354 return ((long *)p1)[1] - ((long *)p2)[1];
355}
356static int sort_down(const void *p1, const void *p2)
357{
358 return ((long *)p2)[1] - ((long *)p1)[1];
359}
360static int sort_random(const void *p1, const void *p2)
361{
362 return (rand() % 1) ? -1 : 1;
363}
364static int sort_dvi_up(const void *p1, const void *p2)
365{
366 return ((long *)p1)[0] - ((long *)p2)[0];
367}
368static int sort_dvi_down(const void *p1, const void *p2)
369{
370 return ((long *)p1)[0] - ((long *)p2)[0];
371}
372
373void mdvi_sort_pages(DviContext *dvi, DviPageSort type)
374{
375 int (*sortfunc) __PROTO((const void *, const void *))(const void *, const void *);
376
377 switch(type) {
378 case MDVI_PAGE_SORT_UP:
379 sortfunc = sort_up;
380 break;
381 case MDVI_PAGE_SORT_DOWN:
382 sortfunc = sort_down;
383 break;
384 case MDVI_PAGE_SORT_RANDOM:
385 sortfunc = sort_random;
386 break;
387 case MDVI_PAGE_SORT_DVI_UP:
388 sortfunc = sort_dvi_up;
389 break;
390 case MDVI_PAGE_SORT_DVI_DOWN:
391 sortfunc = sort_dvi_down;
392 break;
393 case MDVI_PAGE_SORT_NONE:
394 default:
395 sortfunc = NULL((void*)0);
396 break;
397 }
398
399 if(sortfunc)
400 qsort(dvi->pagemap, dvi->npages, sizeof(PageNum), sortfunc);
401}
402
403static DviFontRef *define_font(DviContext *dvi, int op)
404{
405 Int32 arg;
406 Int32 scale;
407 Int32 dsize;
408 Int32 checksum;
409 int hdpi;
410 int vdpi;
411 int n;
412 char *name;
413 DviFontRef *ref;
414
415 arg = dugetn(dvi, op - DVI_FNT_DEF1243 + 1);
416 checksum = duget4(dvi)dugetn((dvi), 4);
417 scale = duget4(dvi)dugetn((dvi), 4);
418 dsize = duget4(dvi)dugetn((dvi), 4);
419 hdpi = FROUND(dvi->params.mag * dvi->params.dpi * scale / dsize)(int)((dvi->params.mag * dvi->params.dpi * scale / dsize
) + 0.5)
;
420 vdpi = FROUND(dvi->params.mag * dvi->params.vdpi * scale / dsize)(int)((dvi->params.mag * dvi->params.vdpi * scale / dsize
) + 0.5)
;
421 n = duget1(dvi)dugetn((dvi), 1) + duget1(dvi)dugetn((dvi), 1);
422 name = mdvi_malloc(n + 1);
423 dread(dvi, name, n);
424 name[n] = 0;
425 DEBUG((DBG_FONTS, "requesting font %d = `%s' at %.1fpt (%dx%d dpi)\n",__debug ((1 << 1), "requesting font %d = `%s' at %.1fpt (%dx%d dpi)\n"
, arg, name, (double)scale / (dvi->params.tfm_conv * 0x100000
), hdpi, vdpi)
426 arg, name, (double)scale / (dvi->params.tfm_conv * 0x100000),__debug ((1 << 1), "requesting font %d = `%s' at %.1fpt (%dx%d dpi)\n"
, arg, name, (double)scale / (dvi->params.tfm_conv * 0x100000
), hdpi, vdpi)
427 hdpi, vdpi))__debug ((1 << 1), "requesting font %d = `%s' at %.1fpt (%dx%d dpi)\n"
, arg, name, (double)scale / (dvi->params.tfm_conv * 0x100000
), hdpi, vdpi)
;
428 ref = font_reference(&dvi->params, arg, name, checksum, hdpi, vdpi, scale);
429 if(ref == NULL((void*)0)) {
430 mdvi_error(_("could not load font `%s'\n")gettext("could not load font `%s'\n"), name);
431 mdvi_free(name);
432 return NULL((void*)0);
433 }
434 mdvi_free(name);
435 return ref;
436}
437
438static char *opendvi(const char *name)
439{
440 int len;
441 char *file;
442
443 len = strlen(name);
444 /* if file ends with .dvi and it exists, that's it */
445 if(len >= 4 && STREQ(name+len-4, ".dvi")(((name+len-4) != ((void*)0)) && ((".dvi") != ((void*
)0)) && (strcmp (name+len-4, ".dvi") == 0))
) {
446 DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", name))__debug ((1 << 3)|(1 << 2), "opendvi: Trying `%s'\n"
, name)
;
447 if(access(name, R_OK4) == 0)
448 return mdvi_strdup(name);
449 }
450
451 /* try appending .dvi */
452 file = mdvi_malloc(len + 5);
453 strcpy(file, name);
454 strcpy(file+len, ".dvi");
455 DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", file))__debug ((1 << 3)|(1 << 2), "opendvi: Trying `%s'\n"
, file)
;
456 if(access(file, R_OK4) == 0)
457 return file;
458 /* try the given name */
459 file[len] = 0;
460 DEBUG((DBG_DVI|DBG_FILES, "opendvi: Trying `%s'\n", file))__debug ((1 << 3)|(1 << 2), "opendvi: Trying `%s'\n"
, file)
;
461 if(access(file, R_OK4) == 0)
462 return file;
463 mdvi_free(file);
464 return NULL((void*)0);
465}
466
467int mdvi_reload(DviContext *dvi, DviParams *np)
468{
469 DviContext *newdvi;
470 DviParams *pars;
471
472 /* close our file */
473 if(dvi->in) {
474 fclosekpse_fclose_trace(dvi->in);
475 dvi->in = NULL((void*)0);
476 }
477
478 pars = np ? np : &dvi->params;
479 DEBUG((DBG_DVI, "%s: reloading\n", dvi->filename))__debug ((1 << 3), "%s: reloading\n", dvi->filename);
480
481 /* load it again */
482 newdvi = mdvi_init_context(pars, dvi->pagesel, dvi->filename);
483 if(newdvi == NULL((void*)0)) {
484 mdvi_warning(_("could not reload `%s'\n")gettext("could not reload `%s'\n"), dvi->filename);
485 return -1;
486 }
487
488 /* drop all our font references */
489 font_drop_chain(dvi->fonts);
490 /* destroy our font map */
491 if(dvi->fontmap)
492 mdvi_free(dvi->fontmap);
493 dvi->currfont = NULL((void*)0);
494
495 /* and use the ones we just loaded */
496 dvi->fonts = newdvi->fonts;
497 dvi->fontmap = newdvi->fontmap;
498 dvi->nfonts = newdvi->nfonts;
499
500 /* copy the new information */
501 dvi->params = newdvi->params;
502 dvi->num = newdvi->num;
503 dvi->den = newdvi->den;
504 dvi->dvimag = newdvi->dvimag;
505 dvi->dviconv = newdvi->dviconv;
506 dvi->dvivconv = newdvi->dvivconv;
507 dvi->modtime = newdvi->modtime;
508
509 if(dvi->fileid) mdvi_free(dvi->fileid);
510 dvi->fileid = newdvi->fileid;
511
512 dvi->dvi_page_w = newdvi->dvi_page_w;
513 dvi->dvi_page_h = newdvi->dvi_page_h;
514
515 mdvi_free(dvi->pagemap);
516 dvi->pagemap = newdvi->pagemap;
517 dvi->npages = newdvi->npages;
518 if(dvi->currpage > dvi->npages-1)
519 dvi->currpage = 0;
520
521 mdvi_free(dvi->stack);
522 dvi->stack = newdvi->stack;
523 dvi->stacksize = newdvi->stacksize;
524
525 /* remove fonts that are not being used anymore */
526 font_free_unused(&dvi->device);
527
528 mdvi_free(newdvi->filename);
529 mdvi_free(newdvi);
530
531 DEBUG((DBG_DVI, "%s: reload successful\n", dvi->filename))__debug ((1 << 3), "%s: reload successful\n", dvi->filename
)
;
532 if(dvi->device.refresh)
533 dvi->device.refresh(dvi, dvi->device.device_data);
534
535 return 0;
536}
537
538/* function to change parameters ia DVI context
539 * The DVI context is modified ONLY if this function is successful */
540int mdvi_configure(DviContext *dvi, DviParamCode option, ...)
541{
542 va_list ap;
543 int reset_all;
544 int reset_font;
545 DviParams np;
546
547 va_start(ap, option)__builtin_va_start(ap, option);
548
549 reset_font = 0;
550 reset_all = 0;
551 np = dvi->params; /* structure copy */
552 while(option != MDVI_PARAM_LAST) {
553 switch(option) {
554 case MDVI_SET_DPI:
555 np.dpi = np.vdpi = va_arg(ap, Uint)__builtin_va_arg(ap, Uint);
556 reset_all = 1;
557 break;
558 case MDVI_SET_XDPI:
559 np.dpi = va_arg(ap, Uint)__builtin_va_arg(ap, Uint);
560 reset_all = 1;
561 break;
562 case MDVI_SET_YDPI:
563 np.vdpi = va_arg(ap, Uint)__builtin_va_arg(ap, Uint);
564 break;
565 case MDVI_SET_SHRINK:
566 np.hshrink = np.vshrink = va_arg(ap, Uint)__builtin_va_arg(ap, Uint);
567 reset_font = MDVI_FONTSEL_GREY(1 << 1)|MDVI_FONTSEL_BITMAP(1 << 0);
568 break;
569 case MDVI_SET_XSHRINK:
570 np.hshrink = va_arg(ap, Uint)__builtin_va_arg(ap, Uint);
571 reset_font = MDVI_FONTSEL_GREY(1 << 1)|MDVI_FONTSEL_BITMAP(1 << 0);
572 break;
573 case MDVI_SET_YSHRINK:
574 np.vshrink = va_arg(ap, Uint)__builtin_va_arg(ap, Uint);
575 reset_font = MDVI_FONTSEL_GREY(1 << 1)|MDVI_FONTSEL_BITMAP(1 << 0);
576 break;
577 case MDVI_SET_ORIENTATION:
578 np.orientation = va_arg(ap, DviOrientation)__builtin_va_arg(ap, DviOrientation);
579 reset_font = MDVI_FONTSEL_GLYPH(1 << 2);
580 break;
581 case MDVI_SET_GAMMA:
582 np.gamma = va_arg(ap, double)__builtin_va_arg(ap, double);
583 reset_font = MDVI_FONTSEL_GREY(1 << 1);
584 break;
585 case MDVI_SET_DENSITY:
586 np.density = va_arg(ap, Uint)__builtin_va_arg(ap, Uint);
587 reset_font = MDVI_FONTSEL_BITMAP(1 << 0);
588 break;
589 case MDVI_SET_MAGNIFICATION:
590 np.mag = va_arg(ap, double)__builtin_va_arg(ap, double);
591 reset_all = 1;
592 break;
593 case MDVI_SET_DRIFT:
594 np.hdrift = np.vdrift = va_arg(ap, int)__builtin_va_arg(ap, int);
595 break;
596 case MDVI_SET_HDRIFT:
597 np.hdrift = va_arg(ap, int)__builtin_va_arg(ap, int);
598 break;
599 case MDVI_SET_VDRIFT:
600 np.vdrift = va_arg(ap, int)__builtin_va_arg(ap, int);
601 break;
602 case MDVI_SET_FOREGROUND:
603 np.fg = va_arg(ap, Ulong)__builtin_va_arg(ap, Ulong);
604 reset_font = MDVI_FONTSEL_GREY(1 << 1);
605 break;
606 case MDVI_SET_BACKGROUND:
607 np.bg = va_arg(ap, Ulong)__builtin_va_arg(ap, Ulong);
608 reset_font = MDVI_FONTSEL_GREY(1 << 1);
609 break;
610 default:
611 break;
612 }
613 option = va_arg(ap, DviParamCode)__builtin_va_arg(ap, DviParamCode);
614 }
615 va_end(ap)__builtin_va_end(ap);
616
617 /* check that all values make sense */
618 if(np.dpi <= 0 || np.vdpi <= 0)
619 return -1;
620 if(np.mag <= 0.0)
621 return -1;
622 if(np.density < 0)
623 return -1;
624 if(np.hshrink < 1 || np.vshrink < 1)
625 return -1;
626 if(np.hdrift < 0 || np.vdrift < 0)
627 return -1;
628 if(np.fg == np.bg)
629 return -1;
630
631 /*
632 * If the dpi or the magnification change, we basically have to reload
633 * the DVI file again from scratch.
634 */
635
636 if(reset_all)
637 return (mdvi_reload(dvi, &np) == 0);
638
639 if(np.hshrink != dvi->params.hshrink) {
640 np.conv = dvi->dviconv;
641 if(np.hshrink)
642 np.conv /= np.hshrink;
643 }
644 if(np.vshrink != dvi->params.vshrink) {
645 np.vconv = dvi->dvivconv;
646 if(np.vshrink)
647 np.vconv /= np.vshrink;
648 }
649
650 if(reset_font) {
651 font_reset_chain_glyphs(&dvi->device, dvi->fonts, reset_font);
652 }
653 dvi->params = np;
654 if((reset_font & MDVI_FONTSEL_GLYPH(1 << 2)) && dvi->device.refresh) {
655 dvi->device.refresh(dvi, dvi->device.device_data);
656 return 0;
657 }
658
659 return 1;
660}
661/*
662 * Read the initial data from the DVI file. If something is wrong with the
663 * file, we just spit out an error message and refuse to load the file,
664 * without giving any details. This makes sense because DVI files are ok
665 * 99.99% of the time, and dvitype(1) can be used to check the other 0.01%.
666 */
667DviContext *mdvi_init_context(DviParams *par, DviPageSpec *spec, const char *file)
668{
669 FILE *p;
670 Int32 arg;
671 int op;
672 long offset;
673 int n;
674 DviContext *dvi;
675 char *filename;
676 int pagecount;
677
678 /*
679 * 1. Open the file and initialize the DVI context
680 */
681
682 filename = opendvi(file);
683 if(filename == NULL((void*)0)) {
684 perror(file);
685 return NULL((void*)0);
686 }
687 p = fopenkpse_fopen_trace(filename, "rb");
688 if(p == NULL((void*)0)) {
689 perror(file);
690 mdvi_free(filename);
691 return NULL((void*)0);
692 }
693 dvi = xalloc(DviContext)(DviContext *)mdvi_malloc(sizeof(DviContext));
694 memzero(dvi, sizeof(DviContext))memset((dvi), 0, (sizeof(DviContext)));
695 dvi->pagemap = NULL((void*)0);
696 dvi->filename = filename;
697 dvi->stack = NULL((void*)0);
698 dvi->modtime = get_mtime(fileno(p));
699 dvi->buffer.data = NULL((void*)0);
700 dvi->pagesel = spec;
701 dvi->in = p; /* now we can use the dget*() functions */
702
703 /*
704 * 2. Read the preamble, extract scaling information, and
705 * setup the DVI parameters.
706 */
707
708 if(fuget1(p)((unsigned)getc(p)) != DVI_PRE247)
709 goto bad_dvi;
710 if((arg = fuget1(p)((unsigned)getc(p))) != DVI_ID2) {
711 mdvi_error(_("%s: unsupported DVI format (version %u)\n")gettext("%s: unsupported DVI format (version %u)\n"),
712 file, arg);
713 goto error; /* jump to the end of this routine,
714 * where we handle errors */
715 }
716 /* get dimensions */
717 dvi->num = fuget4(p)fugetn((p), 4);
718 dvi->den = fuget4(p)fugetn((p), 4);
719 dvi->dvimag = fuget4(p)fugetn((p), 4);
720
721 /* check that these numbers make sense */
722 if(!dvi->num || !dvi->den || !dvi->dvimag)
723 goto bad_dvi;
724
725 dvi->params.mag =
726 (par->mag > 0 ? par->mag : (double)dvi->dvimag / 1000.0);
727 dvi->params.hdrift = par->hdrift;
728 dvi->params.vdrift = par->vdrift;
729 dvi->params.dpi = par->dpi ? par->dpi : MDVI_DPI600;
730 dvi->params.vdpi = par->vdpi ? par->vdpi : par->dpi;
731 dvi->params.hshrink = par->hshrink;
732 dvi->params.vshrink = par->vshrink;
733 dvi->params.density = par->density;
734 dvi->params.gamma = par->gamma;
735 dvi->params.conv = (double)dvi->num / dvi->den;
736 dvi->params.conv *= (dvi->params.dpi / 254000.0) * dvi->params.mag;
737 dvi->params.vconv = (double)dvi->num / dvi->den;
738 dvi->params.vconv *= (dvi->params.vdpi / 254000.0) * dvi->params.mag;
739 dvi->params.tfm_conv = (25400000.0 / dvi->num) *
740 ((double)dvi->den / 473628672) / 16.0;
741 dvi->params.flags = par->flags;
742 dvi->params.orientation = par->orientation;
743 dvi->params.fg = par->fg;
744 dvi->params.bg = par->bg;
745
746 /* initialize colors */
747 dvi->curr_fg = par->fg;
748 dvi->curr_bg = par->bg;
749 dvi->color_stack = NULL((void*)0);
750 dvi->color_top = 0;
751 dvi->color_size = 0;
752
753 /* pixel conversion factors */
754 dvi->dviconv = dvi->params.conv;
755 dvi->dvivconv = dvi->params.vconv;
756 if(dvi->params.hshrink)
757 dvi->params.conv /= dvi->params.hshrink;
758 if(dvi->params.vshrink)
759 dvi->params.vconv /= dvi->params.vshrink;
760
761 /* get the comment from the preamble */
762 n = fuget1(p)((unsigned)getc(p));
763 dvi->fileid = mdvi_malloc(n + 1);
764 fread(dvi->fileid, 1, n, p);
765 dvi->fileid[n] = 0;
766 DEBUG((DBG_DVI, "%s: %s\n", filename, dvi->fileid))__debug ((1 << 3), "%s: %s\n", filename, dvi->fileid
)
;
767
768 /*
769 * 3. Read postamble, extract page information (number of
770 * pages, dimensions) and stack depth.
771 */
772
773 /* jump to the end of the file */
774 if(fseek(p, (long)-1, SEEK_END2) == -1)
775 goto error;
776 for(n = 0; (op = fuget1(p)((unsigned)getc(p))) == DVI_TRAILER223; n++)
777 if(fseek(p, (long)-2, SEEK_CUR1) < 0)
778 break;
779 if(op != arg || n < 4)
780 goto bad_dvi;
781 /* get the pointer to postamble */
782 fseek(p, (long)-5, SEEK_CUR1);
783 arg = fuget4(p)fugetn((p), 4);
784 /* jump to it */
785 fseek(p, (long)arg, SEEK_SET0);
786 if(fuget1(p)((unsigned)getc(p)) != DVI_POST248)
787 goto bad_dvi;
788 offset = fuget4(p)fugetn((p), 4);
789 if(dvi->num != fuget4(p)fugetn((p), 4) || dvi->den != fuget4(p)fugetn((p), 4) ||
790 dvi->dvimag != fuget4(p)fugetn((p), 4))
791 goto bad_dvi;
792 dvi->dvi_page_h = fuget4(p)fugetn((p), 4);
793 dvi->dvi_page_w = fuget4(p)fugetn((p), 4);
794 dvi->stacksize = fuget2(p)fugetn((p), 2);
795 dvi->npages = fuget2(p)fugetn((p), 2);
796 DEBUG((DBG_DVI, "%s: from postamble: stack depth %d, %d page%s\n",__debug ((1 << 3), "%s: from postamble: stack depth %d, %d page%s\n"
, filename, dvi->stacksize, dvi->npages, dvi->npages
> 1 ? "s" : "")
797 filename, dvi->stacksize, dvi->npages, dvi->npages > 1 ? "s" : ""))__debug ((1 << 3), "%s: from postamble: stack depth %d, %d page%s\n"
, filename, dvi->stacksize, dvi->npages, dvi->npages
> 1 ? "s" : "")
;
798
799 /*
800 * 4. Process font definitions.
801 */
802
803 /* process font definitions */
804 dvi->nfonts = 0;
805 dvi->fontmap = NULL((void*)0);
806 /*
807 * CAREFUL: here we need to use the dvi->buffer, but it might leave the
808 * the file cursor in the wrong position after reading fonts (because of
809 * buffering). It's ok, though, because after the font definitions we read
810 * the page offsets, and we fseek() to the relevant part of the file with
811 * SEEK_SET. Nothing is read after the page offsets.
812 */
813 while((op = duget1(dvi)dugetn((dvi), 1)) != DVI_POST_POST249) {
814 DviFontRef *ref;
815
816 if(op == DVI_NOOP138)
817 continue;
818 else if(op < DVI_FNT_DEF1243 || op > DVI_FNT_DEF4246)
819 goto error;
820 ref = define_font(dvi, op);
821 if(ref == NULL((void*)0))
822 goto error;
823 ref->next = dvi->fonts;
824 dvi->fonts = ref;
825 dvi->nfonts++;
826 }
827 /* we don't need the buffer anymore */
828 dreset(dvi);
829
830 if(op != DVI_POST_POST249)
831 goto bad_dvi;
832 font_finish_definitions(dvi);
833 DEBUG((DBG_DVI, "%s: %d font%s required by this job\n",__debug ((1 << 3), "%s: %d font%s required by this job\n"
, filename, dvi->nfonts, dvi->nfonts > 1 ? "s" : "")
834 filename, dvi->nfonts, dvi->nfonts > 1 ? "s" : ""))__debug ((1 << 3), "%s: %d font%s required by this job\n"
, filename, dvi->nfonts, dvi->nfonts > 1 ? "s" : "")
;
835 dvi->findref = font_find_mapped;
836
837 /*
838 * 5. Build the page map.
839 */
840
841 dvi->pagemap = xnalloc(PageNum, dvi->npages)(PageNum *)mdvi_calloc((dvi->npages), sizeof(PageNum));
842 memzero(dvi->pagemap, sizeof(PageNum) * dvi->npages)memset((dvi->pagemap), 0, (sizeof(PageNum) * dvi->npages
))
;
843
844 n = dvi->npages - 1;
845 pagecount = n;
846 while(offset != -1) {
847 int i;
848 PageNum page;
849
850 fseek(p, offset, SEEK_SET0);
851 op = fuget1(p)((unsigned)getc(p));
852 if(op != DVI_BOP139 || n < 0)
853 goto bad_dvi;
854 for(i = 1; i <= 10; i++)
855 page[i] = fsget4(p)fsgetn((p), 4);
856 page[0] = offset;
857 offset = fsget4(p)fsgetn((p), 4);
858 /* check if the page is selected */
859 if(spec && mdvi_page_selected(spec, page, n) == 0) {
860 DEBUG((DBG_DVI, "Page %d (%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld) ignored by request\n",__debug ((1 << 3), "Page %d (%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld) ignored by request\n"
, n, page[1], page[2], page[3], page[4], page[5], page[6], page
[7], page[8], page[9], page[10])
861 n, page[1], page[2], page[3], page[4], page[5],__debug ((1 << 3), "Page %d (%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld) ignored by request\n"
, n, page[1], page[2], page[3], page[4], page[5], page[6], page
[7], page[8], page[9], page[10])
862 page[6], page[7], page[8], page[9], page[10]))__debug ((1 << 3), "Page %d (%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld.%ld) ignored by request\n"
, n, page[1], page[2], page[3], page[4], page[5], page[6], page
[7], page[8], page[9], page[10])
;
863 } else {
864 memcpy(&dvi->pagemap[pagecount], page, sizeof(PageNum))bcopy ((page), (&dvi->pagemap[pagecount]), (sizeof(PageNum
)))
;
865 pagecount--;
866 }
867 n--;
868 }
869 pagecount++;
870 if(pagecount >= dvi->npages) {
871 mdvi_error(_("no pages selected\n")gettext("no pages selected\n"));
872 goto error;
873 }
874 if(pagecount) {
875 DEBUG((DBG_DVI, "%d of %d pages selected\n",__debug ((1 << 3), "%d of %d pages selected\n", dvi->
npages - pagecount, dvi->npages)
876 dvi->npages - pagecount, dvi->npages))__debug ((1 << 3), "%d of %d pages selected\n", dvi->
npages - pagecount, dvi->npages)
;
877 dvi->npages -= pagecount;
878 memmove(dvi->pagemap, &dvi->pagemap[pagecount],
879 dvi->npages * sizeof(PageNum));
880 }
881
882 /*
883 * 6. Setup stack, initialize device functions
884 */
885
886 dvi->curr_layer = 0;
887 dvi->stack = xnalloc(DviState, dvi->stacksize + 8)(DviState *)mdvi_calloc((dvi->stacksize + 8), sizeof(DviState
))
;
888
889 dvi->device.draw_glyph = dummy_draw_glyph;
890 dvi->device.draw_rule = dummy_draw_rule;
891 dvi->device.alloc_colors = dummy_alloc_colors;
892 dvi->device.create_image = dummy_create_image;
893 dvi->device.free_image = dummy_free_image;
894 dvi->device.dev_destroy = dummy_dev_destroy;
895 dvi->device.put_pixel = dummy_dev_putpixel;
896 dvi->device.refresh = dummy_dev_refresh;
897 dvi->device.set_color = dummy_dev_set_color;
898 dvi->device.device_data = NULL((void*)0);
899
900 DEBUG((DBG_DVI, "%s read successfully\n", filename))__debug ((1 << 3), "%s read successfully\n", filename);
901 return dvi;
902
903bad_dvi:
904 mdvi_error(_("%s: File corrupted, or not a DVI file\n")gettext("%s: File corrupted, or not a DVI file\n"), file);
905error:
906 /* if we came from the font definitions, this will be non-trivial */
907 dreset(dvi);
908 mdvi_destroy_context(dvi);
909 return NULL((void*)0);
910}
911
912void mdvi_destroy_context(DviContext *dvi)
913{
914 if(dvi->device.dev_destroy)
915 dvi->device.dev_destroy(dvi->device.device_data);
916 /* release all fonts */
917 if(dvi->fonts) {
918 font_drop_chain(dvi->fonts);
919 font_free_unused(&dvi->device);
920 }
921 if(dvi->fontmap)
922 mdvi_free(dvi->fontmap);
923 if(dvi->filename)
924 mdvi_free(dvi->filename);
925 if(dvi->stack)
926 mdvi_free(dvi->stack);
927 if(dvi->pagemap)
928 mdvi_free(dvi->pagemap);
929 if(dvi->fileid)
930 mdvi_free(dvi->fileid);
931 if(dvi->in)
932 fclosekpse_fclose_trace(dvi->in);
933 if(dvi->buffer.data && !dvi->buffer.frozen)
934 mdvi_free(dvi->buffer.data);
935 if(dvi->color_stack)
936 mdvi_free(dvi->color_stack);
937
938 mdvi_free(dvi);
939}
940
941void mdvi_setpage(DviContext *dvi, int pageno)
942{
943 if(pageno < 0)
944 pageno = 0;
945 if(pageno > dvi->npages-1)
946 pageno = dvi->npages - 1;
947 dvi->currpage = pageno;
948}
949
950static int mdvi_run_macro(DviContext *dvi, Uchar *macro, size_t len)
951{
952 DviFontRef *curr, *fonts;
953 DviBuffer saved_buffer;
954 FILE *saved_file;
955 int opcode;
956 int oldtop;
957
958 dvi->depth++;
959 push(dvi, DVI_PUSH141);
960 dvi->pos.w = 0;
961 dvi->pos.x = 0;
962 dvi->pos.y = 0;
963 dvi->pos.z = 0;
964
965 /* save our state */
966 curr = dvi->currfont;
967 fonts = dvi->fonts;
968 saved_buffer = dvi->buffer;
969 saved_file = dvi->in;
970 dvi->currfont = curr->ref->subfonts;
971 dvi->fonts = curr->ref->subfonts;
972 dvi->buffer.data = macro;
973 dvi->buffer.pos = 0;
974 dvi->buffer.length = len;
975 dvi->buffer.frozen = 1;
976 dvi->in = NULL((void*)0);
977 oldtop = dvi->stacktop;
978
979 /* execute commands */
980 while((opcode = duget1(dvi)dugetn((dvi), 1)) != DVI_EOP140) {
981 if(dvi_commands[opcode](dvi, opcode) < 0)
982 break;
983 }
984 if(opcode != DVI_EOP140)
985 dviwarn(dvi, _("%s: vf macro had errors\n")gettext("%s: vf macro had errors\n"),
986 curr->ref->fontname);
987 if(dvi->stacktop != oldtop)
988 dviwarn(dvi, _("%s: stack not empty after vf macro\n")gettext("%s: stack not empty after vf macro\n"),
989 curr->ref->fontname);
990
991 /* restore things */
992 pop(dvi, DVI_POP142);
993 dvi->currfont = curr;
994 dvi->fonts = fonts;
995 dvi->buffer = saved_buffer;
996 dvi->in = saved_file;
997 dvi->depth--;
998
999 return (opcode != DVI_EOP140 ? -1 : 0);
1000}
1001
1002int mdvi_dopage(DviContext *dvi, int pageno)
1003{
1004 int op;
1005 int ppi;
1006 int reloaded = 0;
1007
1008again:
1009 if(dvi->in == NULL((void*)0)) {
1
Assuming field 'in' is not equal to NULL
1010 /* try reopening the file */
1011 dvi->in = fopenkpse_fopen_trace(dvi->filename, "rb");
1012 if(dvi->in == NULL((void*)0)) {
1013 mdvi_warning(_("%s: could not reopen file (%s)\n")gettext("%s: could not reopen file (%s)\n"),
1014 dvi->filename,
1015 strerror(errno(*__errno_location ())));
1016 return -1;
1017 }
1018 DEBUG((DBG_FILES, "reopen(%s) -> Ok\n", dvi->filename))__debug ((1 << 2), "reopen(%s) -> Ok\n", dvi->filename
)
;
1019 }
1020
1021 /* check if we need to reload the file */
1022 if(!reloaded
1.1
'reloaded' is 0
&& get_mtime(fileno(dvi->in)) > dvi->modtime) {
2
Assuming the condition is false
1023 mdvi_reload(dvi, &dvi->params);
1024 /* we have to reopen the file, again */
1025 reloaded = 1;
1026 goto again;
1027 }
1028
1029 if(pageno < 0 || pageno > dvi->npages-1) {
3
Assuming 'pageno' is >= 0
4
Assuming the condition is false
5
Taking false branch
1030 mdvi_error(_("%s: page %d out of range\n")gettext("%s: page %d out of range\n"),
1031 dvi->filename, pageno);
1032 return -1;
1033 }
1034
1035 fseek(dvi->in, (long)dvi->pagemap[pageno][0], SEEK_SET0);
1036 if((op = fuget1(dvi->in)((unsigned)getc(dvi->in))) != DVI_BOP139) {
6
Assuming the condition is false
7
Taking false branch
1037 mdvi_error(_("%s: bad offset at page %d\n")gettext("%s: bad offset at page %d\n"),
1038 dvi->filename, pageno+1);
1039 return -1;
1040 }
1041
1042 /* skip bop */
1043 fseek(dvi->in, (long)44, SEEK_CUR1);
1044
1045 /* reset state */
1046 dvi->currfont = NULL((void*)0);
1047 memzero(&dvi->pos, sizeof(DviState))memset((&dvi->pos), 0, (sizeof(DviState)));
1048 dvi->stacktop = 0;
1049 dvi->currpage = pageno;
1050 dvi->curr_layer = 0;
1051
1052 if(dvi->buffer.data && !dvi->buffer.frozen)
8
Assuming field 'data' is null
1053 mdvi_free(dvi->buffer.data);
1054
1055 /* reset our buffer */
1056 dvi->buffer.data = NULL((void*)0);
1057 dvi->buffer.length = 0;
1058 dvi->buffer.pos = 0;
1059 dvi->buffer.frozen = 0;
1060
1061#if 0 /* make colors survive page breaks */
1062 /* reset color stack */
1063 mdvi_reset_color(dvi);
1064#endif
1065
1066 /* set max horizontal and vertical drift (from dvips) */
1067 if(dvi->params.hdrift < 0) {
9
Assuming field 'hdrift' is >= 0
10
Taking false branch
1068 ppi = dvi->params.dpi / dvi->params.hshrink; /* shrunk pixels per inch */
1069 if(ppi < 600)
1070 dvi->params.hdrift = ppi / 100;
1071 else if(ppi < 1200)
1072 dvi->params.hdrift = ppi / 200;
1073 else
1074 dvi->params.hdrift = ppi / 400;
1075 }
1076 if(dvi->params.vdrift < 0) {
11
Assuming field 'vdrift' is >= 0
12
Taking false branch
1077 ppi = dvi->params.vdpi / dvi->params.vshrink; /* shrunk pixels per inch */
1078 if(ppi < 600)
1079 dvi->params.vdrift = ppi / 100;
1080 else if(ppi < 1200)
1081 dvi->params.vdrift = ppi / 200;
1082 else
1083 dvi->params.vdrift = ppi / 400;
1084 }
1085
1086 dvi->params.thinsp = FROUND(0.025 * dvi->params.dpi / dvi->params.conv)(int)((0.025 * dvi->params.dpi / dvi->params.conv) + 0.5
)
;
1087 dvi->params.vsmallsp = FROUND(0.025 * dvi->params.vdpi / dvi->params.vconv)(int)((0.025 * dvi->params.vdpi / dvi->params.vconv) + 0.5
)
;
1088
1089 /* execute all the commands in the page */
1090 while((op = duget1(dvi)dugetn((dvi), 1)) != DVI_EOP140) {
13
Loop condition is true. Entering loop body
1091 if(dvi_commands[op](dvi, op) < 0)
14
Out of bound memory access (accessed memory precedes memory block)
1092 break;
1093 }
1094
1095 fflush(stdoutstdout);
1096 fflush(stderrstderr);
1097 if(op != DVI_EOP140)
1098 return -1;
1099 if(dvi->stacktop)
1100 dviwarn(dvi, _("stack not empty at end of page\n")gettext("stack not empty at end of page\n"));
1101 return 0;
1102}
1103
1104static int inline move_vertical(DviContext *dvi, int amount)
1105{
1106 int rvv;
1107
1108 dvi->pos.v += amount;
1109 rvv = vpixel_round(dvi, dvi->pos.v)(int)((dvi)->params.vconv * (dvi->pos.v) + 0.5);
1110 if(!dvi->params.vdrift)
1111 return rvv;
1112 if(amount > dvi->params.vsmallsp || amount <= -dvi->params.vsmallsp)
1113 return rvv;
1114 else {
1115 int newvv;
1116
1117 newvv = dvi->pos.vv + vpixel_round(dvi, amount)(int)((dvi)->params.vconv * (amount) + 0.5);
1118 if(rvv - newvv > dvi->params.vdrift)
1119 return rvv - dvi->params.vdrift;
1120 else if(newvv - rvv > dvi->params.vdrift)
1121 return rvv + dvi->params.vdrift;
1122 else
1123 return newvv;
1124 }
1125}
1126
1127static int inline move_horizontal(DviContext *dvi, int amount)
1128{
1129 int rhh;
1130
1131 dvi->pos.h += amount;
1132 rhh = pixel_round(dvi, dvi->pos.h)(int)((dvi)->params.conv * (dvi->pos.h) + 0.5);
1133 if(!dvi->params.hdrift)
1134 return rhh;
1135 else if(amount > dvi->params.thinsp || amount <= -6 * dvi->params.thinsp)
1136 return rhh;
1137 else {
1138 int newhh;
1139
1140 newhh = dvi->pos.hh + pixel_round(dvi, amount)(int)((dvi)->params.conv * (amount) + 0.5);
1141 if(rhh - newhh > dvi->params.hdrift)
1142 return rhh - dvi->params.hdrift;
1143 else if(newhh - rhh > dvi->params.hdrift)
1144 return rhh + dvi->params.hdrift;
1145 else
1146 return newhh;
1147 }
1148}
1149
1150static void inline fix_after_horizontal(DviContext *dvi)
1151{
1152 int rhh;
1153
1154 rhh = pixel_round(dvi, dvi->pos.h)(int)((dvi)->params.conv * (dvi->pos.h) + 0.5);
1155 if(!dvi->params.hdrift)
1156 dvi->pos.hh = rhh;
1157 else if(rhh - dvi->pos.hh > dvi->params.hdrift)
1158 dvi->pos.hh = rhh - dvi->params.hdrift;
1159 else if(dvi->pos.hh - rhh > dvi->params.hdrift)
1160 dvi->pos.hh = rhh + dvi->params.hdrift;
1161}
1162
1163/* commands */
1164
1165#define DBGSUM(a,b,c)(a), (b) > 0 ? '+' : '-', (b) > 0 ? (b) : -(b), (c) \
1166 (a), (b) > 0 ? '+' : '-', \
1167 (b) > 0 ? (b) : -(b), (c)
1168
1169static void draw_shrink_rule (DviContext *dvi, int x, int y, Uint w, Uint h, int f)
1170{
1171 Ulong fg, bg;
1172
1173 fg = dvi->curr_fg;
1174 bg = dvi->curr_bg;
1175
1176 mdvi_push_color (dvi, fg, bg);
1177 dvi->device.draw_rule(dvi, x, y, w, h, f);
1178 mdvi_pop_color (dvi);
1179
1180 return;
1181}
1182
1183/*
1184 * The only commands that actually draw something are:
1185 * set_char, set_rule
1186 */
1187
1188static void draw_box(DviContext *dvi, DviFontChar *ch)
1189{
1190 DviGlyph *glyph = NULL((void*)0);
1191 int x, y, w, h;
1192
1193 if(!MDVI_GLYPH_UNSET(ch->shrunk.data)((ch->shrunk.data) == ((void*)0)))
1194 glyph = &ch->shrunk;
1195 else if(!MDVI_GLYPH_UNSET(ch->grey.data)((ch->grey.data) == ((void*)0)))
1196 glyph = &ch->grey;
1197 else if(!MDVI_GLYPH_UNSET(ch->glyph.data)((ch->glyph.data) == ((void*)0)))
1198 glyph = &ch->glyph;
1199 if(glyph == NULL((void*)0))
1200 return;
1201 x = glyph->x;
1202 y = glyph->y;
1203 w = glyph->w;
1204 h = glyph->h;
1205 /* this is bad -- we have to undo the orientation */
1206 switch(dvi->params.orientation) {
1207 case MDVI_ORIENT_TBLR:
1208 break;
1209 case MDVI_ORIENT_TBRL:
1210 x = w - x;
1211 break;
1212 case MDVI_ORIENT_BTLR:
1213 y = h - y;
1214 break;
1215 case MDVI_ORIENT_BTRL:
1216 x = w - x;
1217 y = h - y;
1218 break;
1219 case MDVI_ORIENT_RP90:
1220 SWAPINT(w, h)({ int _s = w; w = h; h = _s; });
1221 SWAPINT(x, y)({ int _s = x; x = y; y = _s; });
1222 x = w - x;
1223 break;
1224 case MDVI_ORIENT_RM90:
1225 SWAPINT(w, h)({ int _s = w; w = h; h = _s; });
1226 SWAPINT(x, y)({ int _s = x; x = y; y = _s; });
1227 y = h - y;
1228 break;
1229 case MDVI_ORIENT_IRP90:
1230 SWAPINT(w, h)({ int _s = w; w = h; h = _s; });
1231 SWAPINT(x, y)({ int _s = x; x = y; y = _s; });
1232 break;
1233 case MDVI_ORIENT_IRM90:
1234 SWAPINT(w, h)({ int _s = w; w = h; h = _s; });
1235 SWAPINT(x, y)({ int _s = x; x = y; y = _s; });
1236 x = w - x;
1237 y = h - y;
1238 break;
1239 }
1240
1241 draw_shrink_rule(dvi, dvi->pos.hh - x, dvi->pos.vv - y, w, h, 1);
1242}
1243
1244int set_char(DviContext *dvi, int opcode)
1245{
1246 int num;
1247 int h;
1248 int hh;
1249 DviFontChar *ch;
1250 DviFont *font;
1251
1252 if(opcode < 128)
1253 num = opcode;
1254 else
1255 num = dugetn(dvi, opcode - DVI_SET1128 + 1);
1256 if(dvi->currfont == NULL((void*)0)) {
1257 dvierr(dvi, _("no default font set yet\n")gettext("no default font set yet\n"));
1258 return -1;
1259 }
1260 font = dvi->currfont->ref;
1261 ch = font_get_glyph(dvi, font, num);
1262 if(ch == NULL((void*)0) || ch->missing) {
1263 /* try to display something anyway */
1264 ch = FONTCHAR(font, num)(((num) < font->loc || (num) > font->hic || !(font
)->chars) ? ((void*)0) : &font->chars[(num) - (font
)->loc])
;
1265 if(!glyph_present(ch)((ch) && (ch)->offset)) {
1266 dviwarn(dvi,
1267 _("requested character %d does not exist in `%s'\n")gettext("requested character %d does not exist in `%s'\n"),
1268 num, font->fontname);
1269 return 0;
1270 }
1271 draw_box(dvi, ch);
1272 } else if(dvi->curr_layer <= dvi->params.layer) {
1273 if(ISVIRTUAL(font)((font)->search.info->getglyph == ((void*)0)))
1274 mdvi_run_macro(dvi, (Uchar *)font->private +
1275 ch->offset, ch->width);
1276 else if(ch->width && ch->height)
1277 dvi->device.draw_glyph(dvi, ch,
1278 dvi->pos.hh, dvi->pos.vv);
1279 }
1280 if(opcode >= DVI_PUT1133 && opcode <= DVI_PUT4136) {
1281 SHOWCMD((dvi, "putchar", opcode - DVI_PUT1 + 1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"putchar", opcode - 133 + 1, "char %d (%s)\n", num, dvi->
currfont->ref->fontname); } while(0)
1282 "char %d (%s)\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"putchar", opcode - 133 + 1, "char %d (%s)\n", num, dvi->
currfont->ref->fontname); } while(0)
1283 num, dvi->currfont->ref->fontname))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"putchar", opcode - 133 + 1, "char %d (%s)\n", num, dvi->
currfont->ref->fontname); } while(0)
;
1284 } else {
1285 h = dvi->pos.h + ch->tfmwidth;
1286 hh = dvi->pos.hh + pixel_round(dvi, ch->tfmwidth)(int)((dvi)->params.conv * (ch->tfmwidth) + 0.5);
1287 SHOWCMD((dvi, "setchar", num, "(%d,%d) h:=%d%c%d=%d, hh:=%d (%s)\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"setchar", num, "(%d,%d) h:=%d%c%d=%d, hh:=%d (%s)\n", dvi->
pos.hh, dvi->pos.vv, (dvi->pos.h), (ch->tfmwidth) >
0 ? '+' : '-', (ch->tfmwidth) > 0 ? (ch->tfmwidth) :
-(ch->tfmwidth), (h), hh, font->fontname); } while(0)
1288 dvi->pos.hh, dvi->pos.vv,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"setchar", num, "(%d,%d) h:=%d%c%d=%d, hh:=%d (%s)\n", dvi->
pos.hh, dvi->pos.vv, (dvi->pos.h), (ch->tfmwidth) >
0 ? '+' : '-', (ch->tfmwidth) > 0 ? (ch->tfmwidth) :
-(ch->tfmwidth), (h), hh, font->fontname); } while(0)
1289 DBGSUM(dvi->pos.h, ch->tfmwidth, h), hh,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"setchar", num, "(%d,%d) h:=%d%c%d=%d, hh:=%d (%s)\n", dvi->
pos.hh, dvi->pos.vv, (dvi->pos.h), (ch->tfmwidth) >
0 ? '+' : '-', (ch->tfmwidth) > 0 ? (ch->tfmwidth) :
-(ch->tfmwidth), (h), hh, font->fontname); } while(0)
1290 font->fontname))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"setchar", num, "(%d,%d) h:=%d%c%d=%d, hh:=%d (%s)\n", dvi->
pos.hh, dvi->pos.vv, (dvi->pos.h), (ch->tfmwidth) >
0 ? '+' : '-', (ch->tfmwidth) > 0 ? (ch->tfmwidth) :
-(ch->tfmwidth), (h), hh, font->fontname); } while(0)
;
1291 dvi->pos.h = h;
1292 dvi->pos.hh = hh;
1293 fix_after_horizontal(dvi);
1294 }
1295
1296 return 0;
1297}
1298
1299int set_rule(DviContext *dvi, int opcode)
1300{
1301 Int32 a, b;
1302 int h, w;
1303
1304 a = dsget4(dvi)dsgetn((dvi), 4);
1305 b = dsget4(dvi)dsgetn((dvi), 4); w = rule_round(dvi, b)(int)((dvi)->params.conv * (b) + 0.99999);
1306 if(a > 0 && b > 0) {
1307 h = vrule_round(dvi, a)(int)((dvi)->params.vconv * (a) + 0.99999);
1308 SHOWCMD((dvi, opcode == DVI_SET_RULE ? "setrule" : "putrule", -1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
opcode == 132 ? "setrule" : "putrule", -1, "width %d, height %d (%dx%d pixels)\n"
, b, a, w, h); } while(0)
1309 "width %d, height %d (%dx%d pixels)\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
opcode == 132 ? "setrule" : "putrule", -1, "width %d, height %d (%dx%d pixels)\n"
, b, a, w, h); } while(0)
1310 b, a, w, h))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
opcode == 132 ? "setrule" : "putrule", -1, "width %d, height %d (%dx%d pixels)\n"
, b, a, w, h); } while(0)
;
1311 /* the `draw' functions expect the origin to be at the top left
1312 * corner of the rule, not the bottom left, as in DVI files */
1313 if(dvi->curr_layer <= dvi->params.layer) {
1314 draw_shrink_rule(dvi,
1315 dvi->pos.hh, dvi->pos.vv - h + 1, w, h, 1);
1316 }
1317 } else {
1318 SHOWCMD((dvi, opcode == DVI_SET_RULE ? "setrule" : "putrule", -1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
opcode == 132 ? "setrule" : "putrule", -1, "(moving left only, by %d)\n"
, b); } while(0)
1319 "(moving left only, by %d)\n", b))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
opcode == 132 ? "setrule" : "putrule", -1, "(moving left only, by %d)\n"
, b); } while(0)
;
1320 }
1321
1322 if(opcode == DVI_SET_RULE132) {
1323 dvi->pos.h += b;
1324 dvi->pos.hh += w;
1325 fix_after_horizontal(dvi);
1326 }
1327 return 0;
1328}
1329
1330int no_op(DviContext *dvi, int opcode)
1331{
1332 SHOWCMD((dvi, "noop", -1, ""))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"noop", -1, ""); } while(0)
;
1333 return 0;
1334}
1335
1336int push(DviContext *dvi, int opcode)
1337{
1338 if(dvi->stacktop == dvi->stacksize) {
1339 if(!dvi->depth)
1340 dviwarn(dvi, _("enlarging stack\n")gettext("enlarging stack\n"));
1341 dvi->stacksize += 8;
1342 dvi->stack = xresize(dvi->stack,(DviState *)mdvi_realloc((dvi->stack), (dvi->stacksize)
* sizeof(DviState))
1343 DviState, dvi->stacksize)(DviState *)mdvi_realloc((dvi->stack), (dvi->stacksize)
* sizeof(DviState))
;
1344 }
1345 memcpy(&dvi->stack[dvi->stacktop], &dvi->pos, sizeof(DviState))bcopy ((&dvi->pos), (&dvi->stack[dvi->stacktop
]), (sizeof(DviState)))
;
1346 SHOWCMD((dvi, "push", -1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"push", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
1347 "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"push", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
1348 dvi->stacktop,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"push", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
1349 dvi->pos.h, dvi->pos.v, dvi->pos.w, dvi->pos.x,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"push", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
1350 dvi->pos.y, dvi->pos.z, dvi->pos.hh, dvi->pos.vv))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"push", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
;
1351 dvi->stacktop++;
1352 return 0;
1353}
1354
1355int pop(DviContext *dvi, int opcode)
1356{
1357 if(dvi->stacktop == 0) {
1358 dvierr(dvi, _("stack underflow\n")gettext("stack underflow\n"));
1359 return -1;
1360 }
1361 memcpy(&dvi->pos, &dvi->stack[dvi->stacktop-1], sizeof(DviState))bcopy ((&dvi->stack[dvi->stacktop-1]), (&dvi->
pos), (sizeof(DviState)))
;
1362 SHOWCMD((dvi, "pop", -1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"pop", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
1363 "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"pop", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
1364 dvi->stacktop,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"pop", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
1365 dvi->pos.h, dvi->pos.v, dvi->pos.w, dvi->pos.x,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"pop", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
1366 dvi->pos.y, dvi->pos.z, dvi->pos.hh, dvi->pos.vv))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"pop", -1, "level %d: (h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=%d,vv=%d)\n"
, dvi->stacktop, dvi->pos.h, dvi->pos.v, dvi->pos
.w, dvi->pos.x, dvi->pos.y, dvi->pos.z, dvi->pos.
hh, dvi->pos.vv); } while(0)
;
1367 dvi->stacktop--;
1368 return 0;
1369}
1370
1371int move_right(DviContext *dvi, int opcode)
1372{
1373 Int32 arg;
1374 int h, hh;
1375
1376 arg = dsgetn(dvi, opcode - DVI_RIGHT1143 + 1);
1377 h = dvi->pos.h;
1378 hh = move_horizontal(dvi, arg);
1379 SHOWCMD((dvi, "right", opcode - DVI_RIGHT1 + 1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"right", opcode - 143 + 1, "%d h:=%d%c%d=%d, hh:=%d\n", arg,
(h), (arg) > 0 ? '+' : '-', (arg) > 0 ? (arg) : -(arg)
, (dvi->pos.h), hh); } while(0)
1380 "%d h:=%d%c%d=%d, hh:=%d\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"right", opcode - 143 + 1, "%d h:=%d%c%d=%d, hh:=%d\n", arg,
(h), (arg) > 0 ? '+' : '-', (arg) > 0 ? (arg) : -(arg)
, (dvi->pos.h), hh); } while(0)
1381 arg, DBGSUM(h, arg, dvi->pos.h), hh))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"right", opcode - 143 + 1, "%d h:=%d%c%d=%d, hh:=%d\n", arg,
(h), (arg) > 0 ? '+' : '-', (arg) > 0 ? (arg) : -(arg)
, (dvi->pos.h), hh); } while(0)
;
1382 dvi->pos.hh = hh;
1383 return 0;
1384}
1385
1386int move_down(DviContext *dvi, int opcode)
1387{
1388 Int32 arg;
1389 int v, vv;
1390
1391 arg = dsgetn(dvi, opcode - DVI_DOWN1157 + 1);
1392 v = dvi->pos.v;
1393 vv = move_vertical(dvi, arg);
1394 SHOWCMD((dvi, "down", opcode - DVI_DOWN1 + 1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"down", opcode - 157 + 1, "%d v:=%d%c%d=%d, vv:=%d\n", arg, (
v), (arg) > 0 ? '+' : '-', (arg) > 0 ? (arg) : -(arg), (
dvi->pos.v), vv); } while(0)
1395 "%d v:=%d%c%d=%d, vv:=%d\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"down", opcode - 157 + 1, "%d v:=%d%c%d=%d, vv:=%d\n", arg, (
v), (arg) > 0 ? '+' : '-', (arg) > 0 ? (arg) : -(arg), (
dvi->pos.v), vv); } while(0)
1396 arg, DBGSUM(v, arg, dvi->pos.v), vv))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"down", opcode - 157 + 1, "%d v:=%d%c%d=%d, vv:=%d\n", arg, (
v), (arg) > 0 ? '+' : '-', (arg) > 0 ? (arg) : -(arg), (
dvi->pos.v), vv); } while(0)
;
1397 dvi->pos.vv = vv;
1398 return 0;
1399}
1400
1401int move_w(DviContext *dvi, int opcode)
1402{
1403 int h, hh;
1404
1405 if(opcode != DVI_W0147)
1406 dvi->pos.w = dsgetn(dvi, opcode - DVI_W0147);
1407 h = dvi->pos.h;
1408 hh = move_horizontal(dvi, dvi->pos.w);
1409 SHOWCMD((dvi, "w", opcode - DVI_W0,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"w", opcode - 147, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
w, (h), (dvi->pos.w) > 0 ? '+' : '-', (dvi->pos.w) >
0 ? (dvi->pos.w) : -(dvi->pos.w), (dvi->pos.h), hh)
; } while(0)
1410 "%d h:=%d%c%d=%d, hh:=%d\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"w", opcode - 147, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
w, (h), (dvi->pos.w) > 0 ? '+' : '-', (dvi->pos.w) >
0 ? (dvi->pos.w) : -(dvi->pos.w), (dvi->pos.h), hh)
; } while(0)
1411 dvi->pos.w, DBGSUM(h, dvi->pos.w, dvi->pos.h), hh))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"w", opcode - 147, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
w, (h), (dvi->pos.w) > 0 ? '+' : '-', (dvi->pos.w) >
0 ? (dvi->pos.w) : -(dvi->pos.w), (dvi->pos.h), hh)
; } while(0)
;
1412 dvi->pos.hh = hh;
1413 return 0;
1414}
1415
1416int move_x(DviContext *dvi, int opcode)
1417{
1418 int h, hh;
1419
1420 if(opcode != DVI_X0152)
1421 dvi->pos.x = dsgetn(dvi, opcode - DVI_X0152);
1422 h = dvi->pos.h;
1423 hh = move_horizontal(dvi, dvi->pos.x);
1424 SHOWCMD((dvi, "x", opcode - DVI_X0,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"x", opcode - 152, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
x, (h), (dvi->pos.x) > 0 ? '+' : '-', (dvi->pos.x) >
0 ? (dvi->pos.x) : -(dvi->pos.x), (dvi->pos.h), hh)
; } while(0)
1425 "%d h:=%d%c%d=%d, hh:=%d\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"x", opcode - 152, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
x, (h), (dvi->pos.x) > 0 ? '+' : '-', (dvi->pos.x) >
0 ? (dvi->pos.x) : -(dvi->pos.x), (dvi->pos.h), hh)
; } while(0)
1426 dvi->pos.x, DBGSUM(h, dvi->pos.x, dvi->pos.h), hh))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"x", opcode - 152, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
x, (h), (dvi->pos.x) > 0 ? '+' : '-', (dvi->pos.x) >
0 ? (dvi->pos.x) : -(dvi->pos.x), (dvi->pos.h), hh)
; } while(0)
;
1427 dvi->pos.hh = hh;
1428 return 0;
1429}
1430
1431int move_y(DviContext *dvi, int opcode)
1432{
1433 int v, vv;
1434
1435 if(opcode != DVI_Y0161)
1436 dvi->pos.y = dsgetn(dvi, opcode - DVI_Y0161);
1437 v = dvi->pos.v;
1438 vv = move_vertical(dvi, dvi->pos.y);
1439 SHOWCMD((dvi, "y", opcode - DVI_Y0,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"y", opcode - 161, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
y, (v), (dvi->pos.y) > 0 ? '+' : '-', (dvi->pos.y) >
0 ? (dvi->pos.y) : -(dvi->pos.y), (dvi->pos.v), vv)
; } while(0)
1440 "%d h:=%d%c%d=%d, hh:=%d\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"y", opcode - 161, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
y, (v), (dvi->pos.y) > 0 ? '+' : '-', (dvi->pos.y) >
0 ? (dvi->pos.y) : -(dvi->pos.y), (dvi->pos.v), vv)
; } while(0)
1441 dvi->pos.y, DBGSUM(v, dvi->pos.y, dvi->pos.v), vv))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"y", opcode - 161, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
y, (v), (dvi->pos.y) > 0 ? '+' : '-', (dvi->pos.y) >
0 ? (dvi->pos.y) : -(dvi->pos.y), (dvi->pos.v), vv)
; } while(0)
;
1442 dvi->pos.vv = vv;
1443 return 0;
1444}
1445
1446int move_z(DviContext *dvi, int opcode)
1447{
1448 int v, vv;
1449
1450 if(opcode != DVI_Z0166)
1451 dvi->pos.z = dsgetn(dvi, opcode - DVI_Z0166);
1452 v = dvi->pos.v;
1453 vv = move_vertical(dvi, dvi->pos.z);
1454 SHOWCMD((dvi, "z", opcode - DVI_Z0,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"z", opcode - 166, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
z, (v), (dvi->pos.z) > 0 ? '+' : '-', (dvi->pos.z) >
0 ? (dvi->pos.z) : -(dvi->pos.z), (dvi->pos.v), vv)
; } while(0)
1455 "%d h:=%d%c%d=%d, hh:=%d\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"z", opcode - 166, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
z, (v), (dvi->pos.z) > 0 ? '+' : '-', (dvi->pos.z) >
0 ? (dvi->pos.z) : -(dvi->pos.z), (dvi->pos.v), vv)
; } while(0)
1456 dvi->pos.z, DBGSUM(v, dvi->pos.z, dvi->pos.v), vv))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"z", opcode - 166, "%d h:=%d%c%d=%d, hh:=%d\n", dvi->pos.
z, (v), (dvi->pos.z) > 0 ? '+' : '-', (dvi->pos.z) >
0 ? (dvi->pos.z) : -(dvi->pos.z), (dvi->pos.v), vv)
; } while(0)
;
1457 dvi->pos.vv = vv;
1458 return 0;
1459}
1460
1461int sel_font(DviContext *dvi, int opcode)
1462{
1463 DviFontRef *ref;
1464 int ndx;
1465
1466 ndx = opcode - DVI_FNT_NUM0171;
1467 if(dvi->depth)
1468 ref = font_find_flat(dvi, ndx);
1469 else
1470 ref = dvi->findref(dvi, ndx);
1471 if(ref == NULL((void*)0)) {
1472 dvierr(dvi, _("font %d is not defined\n")gettext("font %d is not defined\n"),
1473 opcode - DVI_FNT_NUM0171);
1474 return -1;
1475 }
1476 SHOWCMD((dvi, "fntnum", opcode - DVI_FNT_NUM0,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fntnum", opcode - 171, "current font is %s\n", ref->ref->
fontname); } while(0)
1477 "current font is %s\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fntnum", opcode - 171, "current font is %s\n", ref->ref->
fontname); } while(0)
1478 ref->ref->fontname))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fntnum", opcode - 171, "current font is %s\n", ref->ref->
fontname); } while(0)
;
1479 dvi->currfont = ref;
1480 return 0;
1481}
1482
1483int sel_fontn(DviContext *dvi, int opcode)
1484{
1485 Int32 arg;
1486 DviFontRef *ref;
1487
1488 arg = dugetn(dvi, opcode - DVI_FNT1235 + 1);
1489 if(dvi->depth)
1490 ref = font_find_flat(dvi, arg);
1491 else
1492 ref = dvi->findref(dvi, arg);
1493 if(ref == NULL((void*)0)) {
1494 dvierr(dvi, _("font %d is not defined\n")gettext("font %d is not defined\n"), arg);
1495 return -1;
1496 }
1497 SHOWCMD((dvi, "fnt", opcode - DVI_FNT1 + 1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fnt", opcode - 235 + 1, "current font is %s (id %d)\n", ref
->ref->fontname, arg); } while(0)
1498 "current font is %s (id %d)\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fnt", opcode - 235 + 1, "current font is %s (id %d)\n", ref
->ref->fontname, arg); } while(0)
1499 ref->ref->fontname, arg))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fnt", opcode - 235 + 1, "current font is %s (id %d)\n", ref
->ref->fontname, arg); } while(0)
;
1500 dvi->currfont = ref;
1501 return 0;
1502}
1503
1504int special(DviContext *dvi, int opcode)
1505{
1506 char *s;
1507 Int32 arg;
1508
1509 arg = dugetn(dvi, opcode - DVI_XXX1239 + 1);
1510 if (arg <= 0) {
1511 dvierr(dvi, _("malformed special length\n")gettext("malformed special length\n"));
1512 return -1;
1513 }
1514 s = mdvi_malloc(arg + 1);
1515 dread(dvi, s, arg);
1516 s[arg] = 0;
1517 mdvi_do_special(dvi, s);
1518 SHOWCMD((dvi, "XXXX", opcode - DVI_XXX1 + 1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"XXXX", opcode - 239 + 1, "[%s]", s); } while(0)
1519 "[%s]", s))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"XXXX", opcode - 239 + 1, "[%s]", s); } while(0)
;
1520 mdvi_free(s);
1521 return 0;
1522}
1523
1524int def_font(DviContext *dvi, int opcode)
1525{
1526 DviFontRef *ref;
1527 Int32 arg;
1528
1529 arg = dugetn(dvi, opcode - DVI_FNT_DEF1243 + 1);
1530 if(dvi->depth)
1531 ref = font_find_flat(dvi, arg);
1532 else
1533 ref = dvi->findref(dvi, arg);
1534 /* skip the rest */
1535 dskip(dvi, 12);
1536 dskip(dvi, duget1(dvi)dugetn((dvi), 1) + duget1(dvi)dugetn((dvi), 1));
1537 if(ref == NULL((void*)0)) {
1538 dvierr(dvi, _("font %d is not defined in postamble\n")gettext("font %d is not defined in postamble\n"), arg);
1539 return -1;
1540 }
1541 SHOWCMD((dvi, "fntdef", opcode - DVI_FNT_DEF1 + 1,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fntdef", opcode - 243 + 1, "%d -> %s (%d links)\n", ref->
fontid, ref->ref->fontname, ref->ref->links); } while
(0)
1542 "%d -> %s (%d links)\n",if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fntdef", opcode - 243 + 1, "%d -> %s (%d links)\n", ref->
fontid, ref->ref->fontname, ref->ref->links); } while
(0)
1543 ref->fontid, ref->ref->fontname,if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fntdef", opcode - 243 + 1, "%d -> %s (%d links)\n", ref->
fontid, ref->ref->fontname, ref->ref->links); } while
(0)
1544 ref->ref->links))if(_mdvi_debug_mask & (1 << 0)) do { dviprint (dvi,
"fntdef", opcode - 243 + 1, "%d -> %s (%d links)\n", ref->
fontid, ref->ref->fontname, ref->ref->links); } while
(0)
;
1545 return 0;
1546}
1547
1548int unexpected(DviContext *dvi, int opcode)
1549{
1550 dvierr(dvi, _("unexpected opcode %d\n")gettext("unexpected opcode %d\n"), opcode);
1551 return -1;
1552}
1553
1554int undefined(DviContext *dvi, int opcode)
1555{
1556 dvierr(dvi, _("undefined opcode %d\n")gettext("undefined opcode %d\n"), opcode);
1557 return -1;
1558}
1559