1 # -*- encoding: utf-8 -*-
4 # Copyright (C) 2002-2011 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2003-2004,2006,2007 Michael Schindler <m-schindler@users.sourceforge.net>
6 # Copyright (C) 2002-2011 André Wobst <wobsta@users.sourceforge.net>
8 # This file is part of PyX (http://pyx.sourceforge.net/).
10 # PyX is free software; you can redistribute it and/or modify
11 # it under the terms of the GNU General Public License as published by
12 # the Free Software Foundation; either version 2 of the License, or
13 # (at your option) any later version.
15 # PyX is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 # GNU General Public License for more details.
20 # You should have received a copy of the GNU General Public License
21 # along with PyX; if not, write to the Free Software
22 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 import cStringIO
, math
, re
, string
, struct
, sys
, warnings
25 from pyx
import bbox
, canvas
, canvasitem
, color
, epsfile
, filelocator
, path
, reader
, trafo
, unit
26 import texfont
, tfmfile
29 _DVI_CHARMIN
= 0 # typeset a character and move right (range min)
30 _DVI_CHARMAX
= 127 # typeset a character and move right (range max)
31 _DVI_SET1234
= 128 # typeset a character and move right
32 _DVI_SETRULE
= 132 # typeset a rule and move right
33 _DVI_PUT1234
= 133 # typeset a character
34 _DVI_PUTRULE
= 137 # typeset a rule
35 _DVI_NOP
= 138 # no operation
36 _DVI_BOP
= 139 # beginning of page
37 _DVI_EOP
= 140 # ending of page
38 _DVI_PUSH
= 141 # save the current positions (h, v, w, x, y, z)
39 _DVI_POP
= 142 # restore positions (h, v, w, x, y, z)
40 _DVI_RIGHT1234
= 143 # move right
41 _DVI_W0
= 147 # move right by w
42 _DVI_W1234
= 148 # move right and set w
43 _DVI_X0
= 152 # move right by x
44 _DVI_X1234
= 153 # move right and set x
45 _DVI_DOWN1234
= 157 # move down
46 _DVI_Y0
= 161 # move down by y
47 _DVI_Y1234
= 162 # move down and set y
48 _DVI_Z0
= 166 # move down by z
49 _DVI_Z1234
= 167 # move down and set z
50 _DVI_FNTNUMMIN
= 171 # set current font (range min)
51 _DVI_FNTNUMMAX
= 234 # set current font (range max)
52 _DVI_FNT1234
= 235 # set current font
53 _DVI_SPECIAL1234
= 239 # special (dvi extention)
54 _DVI_FNTDEF1234
= 243 # define the meaning of a font number
55 _DVI_PRE
= 247 # preamble
56 _DVI_POST
= 248 # postamble beginning
57 _DVI_POSTPOST
= 249 # postamble ending
59 _DVI_VERSION
= 2 # dvi version
61 # position variable indices
73 _READ_POST
= 4 # XXX not used
74 _READ_POSTPOST
= 5 # XXX not used
78 class DVIError(Exception): pass
80 # save and restore colors
82 class _canvasitem(canvasitem
.canvasitem
):
85 # TODO: see TODO in bbox method of canvasitem
89 class _savecolor(_canvasitem
):
90 def processPS(self
, file, writer
, context
, registry
, bbox
):
91 file.write("currentcolor currentcolorspace\n")
93 def processPDF(self
, file, writer
, context
, registry
, bbox
):
97 class _restorecolor(_canvasitem
):
98 def processPS(self
, file, writer
, context
, registry
, bbox
):
99 file.write("setcolorspace setcolor\n")
101 def processPDF(self
, file, writer
, context
, registry
, bbox
):
105 class _savetrafo(_canvasitem
):
106 def processPS(self
, file, writer
, context
, registry
, bbox
):
107 file.write("matrix currentmatrix\n")
109 def processPDF(self
, file, writer
, context
, registry
, bbox
):
113 class _restoretrafo(_canvasitem
):
114 def processPS(self
, file, writer
, context
, registry
, bbox
):
115 file.write("setmatrix\n")
117 def processPDF(self
, file, writer
, context
, registry
, bbox
):
123 def __init__(self
, filename
, debug
=0, debugfile
=sys
.stdout
):
124 """ opens the dvi file and reads the preamble """
125 self
.filename
= filename
127 self
.debugfile
= debugfile
131 self
.activefont
= None
133 # stack of fonts and fontscale currently used (used for VFs)
137 # pointer to currently active page
140 # stack for self.file, self.fonts and self.stack, needed for VF inclusion
143 self
.file = reader
.reader(self
.filename
)
145 # currently read byte in file (for debugging output)
152 def flushtext(self
, fontmap
):
153 """ finish currently active text object """
155 x
, y
, charcodes
= self
.activetext
156 x_pt
, y_pt
= x
* self
.pyxconv
, -y
*self
.pyxconv
157 self
.actpage
.insert(self
.activefont
.text_pt(x_pt
, y_pt
, charcodes
, fontmap
=fontmap
))
159 self
.debugfile
.write("[%s]\n" % "".join([chr(char
) for char
in self
.activetext
[2]]))
160 self
.activetext
= None
162 def putrule(self
, height
, width
, advancepos
, fontmap
):
163 self
.flushtext(fontmap
)
164 x1
= self
.pos
[_POS_H
] * self
.pyxconv
165 y1
= -self
.pos
[_POS_V
] * self
.pyxconv
166 w
= width
* self
.pyxconv
167 h
= height
* self
.pyxconv
169 if height
> 0 and width
> 0:
171 self
.debugfile
.write("%d: %srule height %d, width %d (???x??? pixels)\n" %
172 (self
.filepos
, advancepos
and "set" or "put", height
, width
))
173 self
.actpage
.fill(path
.rect_pt(x1
, y1
, w
, h
))
176 self
.debugfile
.write("%d: %srule height %d, width %d (invisible)\n" %
177 (self
.filepos
, advancepos
and "set" or "put", height
, width
))
181 self
.debugfile
.write(" h:=%d+%d=%d, hh:=???\n" %
182 (self
.pos
[_POS_H
], width
, self
.pos
[_POS_H
]+width
))
183 self
.pos
[_POS_H
] += width
* self
.scale
185 def putchar(self
, char
, advancepos
, id1234
, fontmap
):
186 dx
= advancepos
and self
.activefont
.getwidth_dvi(char
) or 0
189 self
.debugfile
.write("%d: %s%s%d h:=%d+%d=%d, hh:=???\n" %
191 advancepos
and "set" or "put",
192 id1234
and "%i " % id1234
or "char",
194 self
.pos
[_POS_H
], dx
, self
.pos
[_POS_H
]+dx
))
196 if isinstance(self
.activefont
, texfont
.virtualfont
):
197 # virtual font handling
198 afterpos
= list(self
.pos
)
199 afterpos
[_POS_H
] += dx
200 self
._push
_dvistring
(self
.activefont
.getchar(char
), self
.activefont
.getfonts(), afterpos
,
201 self
.activefont
.getsize_pt(), fontmap
)
203 if self
.activetext
is None:
204 self
.activetext
= (self
.pos
[_POS_H
], self
.pos
[_POS_V
], [])
205 self
.activetext
[2].append(char
)
206 self
.pos
[_POS_H
] += dx
208 if (not advancepos
) or self
.singlecharmode
:
209 self
.flushtext(fontmap
)
211 def usefont(self
, fontnum
, id1234
, fontmap
):
212 self
.flushtext(fontmap
)
213 self
.activefont
= self
.fonts
[fontnum
]
215 self
.debugfile
.write("%d: fnt%s%i current font is %s\n" %
217 id1234
and "%i " % id1234
or "num",
219 self
.fonts
[fontnum
].name
))
222 def definefont(self
, cmdnr
, num
, c
, q
, d
, fontname
):
223 # cmdnr: type of fontdef command (only used for debugging output)
225 # q: scaling factor (fix_word)
226 # Note that q is actually s in large parts of the documentation.
227 # d: design size (fix_word)
229 # check whether it's a virtual font by trying to open it. if this fails, it is an ordinary TeX font
231 fontfile
= filelocator
.open(fontname
, [filelocator
.format
.vf
], mode
="rb")
233 afont
= texfont
.TeXfont(fontname
, c
, q
/self
.tfmconv
, d
/self
.tfmconv
, self
.tfmconv
, self
.pyxconv
, self
.debug
>1)
235 afont
= texfont
.virtualfont(fontname
, fontfile
, c
, q
/self
.tfmconv
, d
/self
.tfmconv
, self
.tfmconv
, self
.pyxconv
, self
.debug
>1)
237 self
.fonts
[num
] = afont
240 self
.debugfile
.write("%d: fntdef%d %i: %s\n" % (self
.filepos
, cmdnr
, num
, fontname
))
242 # scale = round((1000.0*self.conv*q)/(self.trueconv*d))
244 # scalestring = scale!=1000 and " scaled %d" % scale or ""
245 # print ("Font %i: %s%s---loaded at size %d DVI units" %
246 # (num, fontname, scalestring, q))
248 # print " (this font is magnified %d%%)" % round(scale/10)
250 def special(self
, s
, fontmap
):
251 x
= self
.pos
[_POS_H
] * self
.pyxconv
252 y
= -self
.pos
[_POS_V
] * self
.pyxconv
254 self
.debugfile
.write("%d: xxx '%s'\n" % (self
.filepos
, s
))
255 if not s
.startswith("PyX:"):
256 warnings
.warn("ignoring special '%s'" % s
)
259 # it is in general not safe to continue using the currently active font because
260 # the specials may involve some gsave/grestore operations
261 self
.flushtext(fontmap
)
263 command
, args
= s
[4:].split()[0], s
[4:].split()[1:]
264 if command
== "color_begin":
265 if args
[0] == "cmyk":
266 c
= color
.cmyk(float(args
[1]), float(args
[2]), float(args
[3]), float(args
[4]))
267 elif args
[0] == "gray":
268 c
= color
.gray(float(args
[1]))
269 elif args
[0] == "hsb":
270 c
= color
.hsb(float(args
[1]), float(args
[2]), float(args
[3]))
271 elif args
[0] == "rgb":
272 c
= color
.rgb(float(args
[1]), float(args
[2]), float(args
[3]))
273 elif args
[0] == "RGB":
274 c
= color
.rgb(int(args
[1])/255.0, int(args
[2])/255.0, int(args
[3])/255.0)
275 elif args
[0] == "texnamed":
277 c
= getattr(color
.cmyk
, args
[1])
278 except AttributeError:
279 raise RuntimeError("unknown TeX color '%s', aborting" % args
[1])
280 elif args
[0] == "pyxcolor":
281 # pyx.color.cmyk.PineGreen or
282 # pyx.color.cmyk(0,0,0,0.0)
283 pat
= re
.compile(r
"(pyx\.)?(color\.)?(?P<model>(cmyk)|(rgb)|(grey)|(gray)|(hsb))[\.]?(?P<arg>.*)")
284 sd
= pat
.match(" ".join(args
[1:]))
287 if sd
["arg"][0] == "(":
288 numpat
= re
.compile(r
"[+-]?((\d+\.\d*)|(\d*\.\d+)|(\d+))([eE][+-]\d+)?")
289 arg
= tuple([float(x
[0]) for x
in numpat
.findall(sd
["arg"])])
291 c
= getattr(color
, sd
["model"])(*arg
)
292 except TypeError or AttributeError:
293 raise RuntimeError("cannot access PyX color '%s' in TeX, aborting" % " ".join(args
[1:]))
296 c
= getattr(getattr(color
, sd
["model"]), sd
["arg"])
297 except AttributeError:
298 raise RuntimeError("cannot access PyX color '%s' in TeX, aborting" % " ".join(args
[1:]))
300 raise RuntimeError("cannot access PyX color '%s' in TeX, aborting" % " ".join(args
[1:]))
302 raise RuntimeError("color model '%s' cannot be handled by PyX, aborting" % args
[0])
303 self
.actpage
.insert(_savecolor())
304 self
.actpage
.insert(c
)
305 elif command
== "color_end":
306 self
.actpage
.insert(_restorecolor())
307 elif command
== "rotate_begin":
308 self
.actpage
.insert(_savetrafo())
309 self
.actpage
.insert(trafo
.rotate_pt(float(args
[0]), x
, y
))
310 elif command
== "rotate_end":
311 self
.actpage
.insert(_restoretrafo())
312 elif command
== "scale_begin":
313 self
.actpage
.insert(_savetrafo())
314 self
.actpage
.insert(trafo
.scale_pt(float(args
[0]), float(args
[1]), x
, y
))
315 elif command
== "scale_end":
316 self
.actpage
.insert(_restoretrafo())
317 elif command
== "epsinclude":
321 name
, value
= arg
.split("=")
322 argdict
[name
] = value
324 # construct kwargs for epsfile constructor
326 epskwargs
["filename"] = argdict
["file"]
327 epskwargs
["bbox"] = bbox
.bbox_pt(float(argdict
["llx"]), float(argdict
["lly"]),
328 float(argdict
["urx"]), float(argdict
["ury"]))
329 if argdict
.has_key("width"):
330 epskwargs
["width"] = float(argdict
["width"]) * unit
.t_pt
331 if argdict
.has_key("height"):
332 epskwargs
["height"] = float(argdict
["height"]) * unit
.t_pt
333 if argdict
.has_key("clip"):
334 epskwargs
["clip"] = int(argdict
["clip"])
335 self
.actpage
.insert(epsfile
.epsfile(x
* unit
.t_pt
, y
* unit
.t_pt
, **epskwargs
))
336 elif command
== "marker":
338 raise RuntimeError("marker contains spaces")
340 if c
not in string
.digits
+ string
.letters
+ "@":
341 raise RuntimeError("marker contains invalid characters")
342 if self
.actpage
.markers
.has_key(args
[0]):
343 raise RuntimeError("marker name occurred several times")
344 self
.actpage
.markers
[args
[0]] = x
* unit
.t_pt
, y
* unit
.t_pt
346 raise RuntimeError("unknown PyX special '%s', aborting" % command
)
348 # routines for pushing and popping different dvi chunks on the reader
350 def _push_dvistring(self
, dvi
, fonts
, afterpos
, fontsize
, fontmap
):
351 """ push dvi string with defined fonts on top of reader
352 stack. Every positions gets scaled relatively by the factor
353 scale. After interpretating the dvi chunk, continue with self.pos=afterpos.
354 The designsize of the virtual font is passed as a fix_word
359 # self.debugfile.write("executing new dvi chunk\n")
360 self
.debugstack
.append(self
.debug
)
363 self
.statestack
.append((self
.file, self
.fonts
, self
.activefont
, afterpos
, self
.stack
, self
.scale
))
365 # units in vf files are relative to the size of the font and given as fix_words
366 # which can be converted to floats by diving by 2**20.
367 # This yields the following scale factor for the height and width of rects:
368 self
.scale
= fontsize
/2**20/self
.pyxconv
370 self
.file = reader
.stringreader(dvi
)
375 self
.usefont(0, 0, fontmap
)
377 def _pop_dvistring(self
, fontmap
):
378 self
.flushtext(fontmap
)
380 # self.debugfile.write("finished executing dvi chunk\n")
381 self
.debug
= self
.debugstack
.pop()
384 self
.file, self
.fonts
, self
.activefont
, self
.pos
, self
.stack
, self
.scale
= self
.statestack
.pop()
386 # routines corresponding to the different reader states of the dvi maschine
391 self
.filepos
= afile
.tell()
392 cmd
= afile
.readuchar()
395 elif cmd
== _DVI_PRE
:
396 if afile
.readuchar() != _DVI_VERSION
: raise DVIError
397 num
= afile
.readuint32()
398 den
= afile
.readuint32()
399 self
.mag
= afile
.readuint32()
401 # For the interpretation of the lengths in dvi and tfm files,
402 # three conversion factors are relevant:
403 # - self.tfmconv: tfm units -> dvi units
404 # - self.pyxconv: dvi units -> (PostScript) points
405 # - self.conv: dvi units -> pixels
406 self
.tfmconv
= (25400000.0/num
)*(den
/473628672.0)/16.0
408 # calculate conv as described in the DVIType docu using
409 # a given resolution in dpi
410 self
.resolution
= 300.0
411 self
.conv
= (num
/254000.0)*(self
.resolution
/den
)
413 # self.pyxconv is the conversion factor from the dvi units
414 # to (PostScript) points. It consists of
415 # - self.mag/1000.0: magstep scaling
416 # - self.conv: conversion from dvi units to pixels
417 # - 1/self.resolution: conversion from pixels to inch
418 # - 72 : conversion from inch to points
419 self
.pyxconv
= self
.mag
/1000.0*self
.conv
/self
.resolution
*72
421 # scaling used for rules when VF chunks are interpreted
424 comment
= afile
.read(afile
.readuchar())
429 def readpage(self
, pageid
=None, fontmap
=None, singlecharmode
=False):
430 """ reads a page from the dvi file
432 This routine reads a page from the dvi file which is
433 returned as a canvas. When there is no page left in the
434 dvifile, None is returned and the file is closed properly."""
436 self
.singlecharmode
= singlecharmode
439 self
.filepos
= self
.file.tell()
440 cmd
= self
.file.readuchar()
443 elif cmd
== _DVI_BOP
:
444 ispageid
= [self
.file.readuint32() for i
in range(10)]
445 if pageid
is not None and ispageid
!= pageid
:
446 raise DVIError("invalid pageid")
448 self
.debugfile
.write("%d: beginning of page %i\n" % (self
.filepos
, ispageid
[0]))
449 self
.file.readuint32()
451 elif cmd
== _DVI_POST
:
453 return None # nothing left
457 self
.actpage
= canvas
.canvas()
458 self
.actpage
.markers
= {}
459 self
.pos
= [0, 0, 0, 0, 0, 0]
461 # tuple (hpos, vpos, codepoints) to be output, or None if no output is pending
462 self
.activetext
= None
466 self
.filepos
= afile
.tell()
468 cmd
= afile
.readuchar()
470 # we most probably (if the dvi file is not corrupt) hit the end of a dvi chunk,
471 # so we have to continue with the rest of the dvi file
472 self
._pop
_dvistring
(fontmap
)
476 if cmd
>= _DVI_CHARMIN
and cmd
<= _DVI_CHARMAX
:
477 self
.putchar(cmd
, True, 0, fontmap
)
478 elif cmd
>= _DVI_SET1234
and cmd
< _DVI_SET1234
+ 4:
479 self
.putchar(afile
.readint(cmd
- _DVI_SET1234
+ 1), True, cmd
-_DVI_SET1234
+1, fontmap
)
480 elif cmd
== _DVI_SETRULE
:
481 self
.putrule(afile
.readint32()*self
.scale
, afile
.readint32()*self
.scale
, True, fontmap
)
482 elif cmd
>= _DVI_PUT1234
and cmd
< _DVI_PUT1234
+ 4:
483 self
.putchar(afile
.readint(cmd
- _DVI_PUT1234
+ 1), False, cmd
-_DVI_SET1234
+1, fontmap
)
484 elif cmd
== _DVI_PUTRULE
:
485 self
.putrule(afile
.readint32()*self
.scale
, afile
.readint32()*self
.scale
, False, fontmap
)
486 elif cmd
== _DVI_EOP
:
487 self
.flushtext(fontmap
)
489 self
.debugfile
.write("%d: eop\n \n" % self
.filepos
)
491 elif cmd
== _DVI_PUSH
:
492 self
.stack
.append(list(self
.pos
))
494 self
.debugfile
.write("%s: push\n"
495 "level %d:(h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=???,vv=???)\n" %
496 ((self
.filepos
, len(self
.stack
)-1) + tuple(self
.pos
)))
497 elif cmd
== _DVI_POP
:
498 self
.flushtext(fontmap
)
499 self
.pos
= self
.stack
.pop()
501 self
.debugfile
.write("%s: pop\n"
502 "level %d:(h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=???,vv=???)\n" %
503 ((self
.filepos
, len(self
.stack
)) + tuple(self
.pos
)))
504 elif cmd
>= _DVI_RIGHT1234
and cmd
< _DVI_RIGHT1234
+ 4:
505 self
.flushtext(fontmap
)
506 dh
= afile
.readint(cmd
- _DVI_RIGHT1234
+ 1, 1) * self
.scale
508 self
.debugfile
.write("%d: right%d %d h:=%d%+d=%d, hh:=???\n" %
510 cmd
- _DVI_RIGHT1234
+ 1,
514 self
.pos
[_POS_H
]+dh
))
515 self
.pos
[_POS_H
] += dh
517 self
.flushtext(fontmap
)
519 self
.debugfile
.write("%d: w0 %d h:=%d%+d=%d, hh:=???\n" %
524 self
.pos
[_POS_H
]+self
.pos
[_POS_W
]))
525 self
.pos
[_POS_H
] += self
.pos
[_POS_W
]
526 elif cmd
>= _DVI_W1234
and cmd
< _DVI_W1234
+ 4:
527 self
.flushtext(fontmap
)
528 self
.pos
[_POS_W
] = afile
.readint(cmd
- _DVI_W1234
+ 1, 1) * self
.scale
530 self
.debugfile
.write("%d: w%d %d h:=%d%+d=%d, hh:=???\n" %
532 cmd
- _DVI_W1234
+ 1,
536 self
.pos
[_POS_H
]+self
.pos
[_POS_W
]))
537 self
.pos
[_POS_H
] += self
.pos
[_POS_W
]
539 self
.flushtext(fontmap
)
541 self
.debugfile
.write("%d: x0 %d h:=%d%+d=%d, hh:=???\n" %
546 self
.pos
[_POS_H
]+self
.pos
[_POS_X
]))
547 self
.pos
[_POS_H
] += self
.pos
[_POS_X
]
548 elif cmd
>= _DVI_X1234
and cmd
< _DVI_X1234
+ 4:
549 self
.flushtext(fontmap
)
550 self
.pos
[_POS_X
] = afile
.readint(cmd
- _DVI_X1234
+ 1, 1) * self
.scale
552 self
.debugfile
.write("%d: x%d %d h:=%d%+d=%d, hh:=???\n" %
554 cmd
- _DVI_X1234
+ 1,
558 self
.pos
[_POS_H
]+self
.pos
[_POS_X
]))
559 self
.pos
[_POS_H
] += self
.pos
[_POS_X
]
560 elif cmd
>= _DVI_DOWN1234
and cmd
< _DVI_DOWN1234
+ 4:
561 self
.flushtext(fontmap
)
562 dv
= afile
.readint(cmd
- _DVI_DOWN1234
+ 1, 1) * self
.scale
564 self
.debugfile
.write("%d: down%d %d v:=%d%+d=%d, vv:=???\n" %
566 cmd
- _DVI_DOWN1234
+ 1,
570 self
.pos
[_POS_V
]+dv
))
571 self
.pos
[_POS_V
] += dv
573 self
.flushtext(fontmap
)
575 self
.debugfile
.write("%d: y0 %d v:=%d%+d=%d, vv:=???\n" %
580 self
.pos
[_POS_V
]+self
.pos
[_POS_Y
]))
581 self
.pos
[_POS_V
] += self
.pos
[_POS_Y
]
582 elif cmd
>= _DVI_Y1234
and cmd
< _DVI_Y1234
+ 4:
583 self
.flushtext(fontmap
)
584 self
.pos
[_POS_Y
] = afile
.readint(cmd
- _DVI_Y1234
+ 1, 1) * self
.scale
586 self
.debugfile
.write("%d: y%d %d v:=%d%+d=%d, vv:=???\n" %
588 cmd
- _DVI_Y1234
+ 1,
592 self
.pos
[_POS_V
]+self
.pos
[_POS_Y
]))
593 self
.pos
[_POS_V
] += self
.pos
[_POS_Y
]
595 self
.flushtext(fontmap
)
597 self
.debugfile
.write("%d: z0 %d v:=%d%+d=%d, vv:=???\n" %
602 self
.pos
[_POS_V
]+self
.pos
[_POS_Z
]))
603 self
.pos
[_POS_V
] += self
.pos
[_POS_Z
]
604 elif cmd
>= _DVI_Z1234
and cmd
< _DVI_Z1234
+ 4:
605 self
.flushtext(fontmap
)
606 self
.pos
[_POS_Z
] = afile
.readint(cmd
- _DVI_Z1234
+ 1, 1) * self
.scale
608 self
.debugfile
.write("%d: z%d %d v:=%d%+d=%d, vv:=???\n" %
610 cmd
- _DVI_Z1234
+ 1,
614 self
.pos
[_POS_V
]+self
.pos
[_POS_Z
]))
615 self
.pos
[_POS_V
] += self
.pos
[_POS_Z
]
616 elif cmd
>= _DVI_FNTNUMMIN
and cmd
<= _DVI_FNTNUMMAX
:
617 self
.usefont(cmd
- _DVI_FNTNUMMIN
, 0, fontmap
)
618 elif cmd
>= _DVI_FNT1234
and cmd
< _DVI_FNT1234
+ 4:
619 # note that according to the DVI docs, for four byte font numbers,
620 # the font number is signed. Don't ask why!
621 fntnum
= afile
.readint(cmd
- _DVI_FNT1234
+ 1, cmd
== _DVI_FNT1234
+ 3)
622 self
.usefont(fntnum
, cmd
-_DVI_FNT1234
+1, fontmap
)
623 elif cmd
>= _DVI_SPECIAL1234
and cmd
< _DVI_SPECIAL1234
+ 4:
624 self
.special(afile
.read(afile
.readint(cmd
- _DVI_SPECIAL1234
+ 1)), fontmap
)
625 elif cmd
>= _DVI_FNTDEF1234
and cmd
< _DVI_FNTDEF1234
+ 4:
626 if cmd
== _DVI_FNTDEF1234
:
627 num
= afile
.readuchar()
628 elif cmd
== _DVI_FNTDEF1234
+1:
629 num
= afile
.readuint16()
630 elif cmd
== _DVI_FNTDEF1234
+2:
631 num
= afile
.readuint24()
632 elif cmd
== _DVI_FNTDEF1234
+3:
633 # Cool, here we have according to docu a signed int. Why?
634 num
= afile
.readint32()
635 self
.definefont(cmd
-_DVI_FNTDEF1234
+1,
640 afile
.read(afile
.readuchar()+afile
.readuchar()))