1 # -*- coding: ISO-8859-1 -*-
4 # Copyright (C) 2002-2006 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-2006 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
, exceptions
, re
, struct
, string
, sys
, warnings
, math
25 from pyx
import unit
, epsfile
, bbox
, canvas
, color
, trafo
, path
, pykpathsea
, reader
26 import tfmfile
, texfont
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(exceptions
.Exception): pass
80 # save and restore colors
82 class _savecolor(canvas
.canvasitem
):
83 def processPS(self
, file, writer
, context
, registry
, bbox
):
84 file.write("currentcolor currentcolorspace\n")
86 def processPDF(self
, file, writer
, context
, registry
, bbox
):
90 class _restorecolor(canvas
.canvasitem
):
91 def processPS(self
, file, writer
, context
, registry
, bbox
):
92 file.write("setcolorspace setcolor\n")
94 def processPDF(self
, file, writer
, context
, registry
, bbox
):
97 class _savetrafo(canvas
.canvasitem
):
98 def processPS(self
, file, writer
, context
, registry
, bbox
):
99 file.write("matrix currentmatrix\n")
101 def processPDF(self
, file, writer
, context
, registry
, bbox
):
105 class _restoretrafo(canvas
.canvasitem
):
106 def processPS(self
, file, writer
, context
, registry
, bbox
):
107 file.write("setmatrix\n")
109 def processPDF(self
, file, writer
, context
, registry
, bbox
):
115 def __init__(self
, filename
, debug
=0, debugfile
=sys
.stdout
):
116 """ opens the dvi file and reads the preamble """
117 self
.filename
= filename
119 self
.debugfile
= debugfile
123 self
.activefont
= None
125 # stack of fonts and fontscale currently used (used for VFs)
129 # pointer to currently active page
132 # stack for self.file, self.fonts and self.stack, needed for VF inclusion
135 self
.file = reader
.reader(self
.filename
)
137 # currently read byte in file (for debugging output)
145 """ finish currently active text object """
147 x
, y
, charcodes
= self
.activetext
148 x_pt
, y_pt
= x
* self
.pyxconv
, -y
*self
.pyxconv
149 self
.actpage
.insert(self
.activefont
.text_pt(x_pt
, y_pt
, charcodes
))
151 self
.debugfile
.write("[%s]\n" % "".join([chr(char
) for char
in self
.activetext
[2]]))
152 self
.activetext
= None
154 def putrule(self
, height
, width
, advancepos
=1):
156 x1
= self
.pos
[_POS_H
] * self
.pyxconv
157 y1
= -self
.pos
[_POS_V
] * self
.pyxconv
158 w
= width
* self
.pyxconv
159 h
= height
* self
.pyxconv
161 if height
> 0 and width
> 0:
163 self
.debugfile
.write("%d: %srule height %d, width %d (???x??? pixels)\n" %
164 (self
.filepos
, advancepos
and "set" or "put", height
, width
))
165 self
.actpage
.fill(path
.rect_pt(x1
, y1
, w
, h
))
168 self
.debugfile
.write("%d: %srule height %d, width %d (invisible)\n" %
169 (self
.filepos
, advancepos
and "set" or "put", height
, width
))
173 self
.debugfile
.write(" h:=%d+%d=%d, hh:=???\n" %
174 (self
.pos
[_POS_H
], width
, self
.pos
[_POS_H
]+width
))
175 self
.pos
[_POS_H
] += width
177 def putchar(self
, char
, advancepos
=1, id1234
=0):
178 dx
= advancepos
and self
.activefont
.getwidth_dvi(char
) or 0
181 self
.debugfile
.write("%d: %s%s%d h:=%d+%d=%d, hh:=???\n" %
183 advancepos
and "set" or "put",
184 id1234
and "%i " % id1234
or "char",
186 self
.pos
[_POS_H
], dx
, self
.pos
[_POS_H
]+dx
))
188 if isinstance(self
.activefont
, texfont
.virtualfont
):
189 # virtual font handling
190 afterpos
= list(self
.pos
)
191 afterpos
[_POS_H
] += dx
192 self
._push
_dvistring
(self
.activefont
.getchar(char
), self
.activefont
.getfonts(), afterpos
,
193 self
.activefont
.getsize_pt())
195 if self
.activetext
is None:
196 self
.activetext
= (self
.pos
[_POS_H
], self
.pos
[_POS_V
], [])
197 self
.activetext
[2].append(char
)
198 self
.pos
[_POS_H
] += dx
203 def usefont(self
, fontnum
, id1234
=0):
205 self
.activefont
= self
.fonts
[fontnum
]
207 self
.debugfile
.write("%d: fnt%s%i current font is %s\n" %
209 id1234
and "%i " % id1234
or "num",
211 self
.fonts
[fontnum
].name
))
214 def definefont(self
, cmdnr
, num
, c
, q
, d
, fontname
):
215 # cmdnr: type of fontdef command (only used for debugging output)
217 # q: scaling factor (fix_word)
218 # Note that q is actually s in large parts of the documentation.
219 # d: design size (fix_word)
221 # check whether it's a virtual font
222 vffontpath
= pykpathsea
.find_file(fontname
, pykpathsea
.kpse_vf_format
)
224 afont
= texfont
.virtualfont(fontname
, vffontpath
, c
, q
/self
.tfmconv
, d
/self
.tfmconv
, self
.tfmconv
, self
.pyxconv
, self
.debug
> 1)
226 afont
= texfont
.TeXfont(fontname
, c
, q
/self
.tfmconv
, d
/self
.tfmconv
, self
.tfmconv
, self
.pyxconv
, self
.debug
> 1)
228 self
.fonts
[num
] = afont
231 self
.debugfile
.write("%d: fntdef%d %i: %s\n" % (self
.filepos
, cmdnr
, num
, fontname
))
233 # scale = round((1000.0*self.conv*q)/(self.trueconv*d))
235 # scalestring = scale!=1000 and " scaled %d" % scale or ""
236 # print ("Font %i: %s%s---loaded at size %d DVI units" %
237 # (num, fontname, scalestring, q))
239 # print " (this font is magnified %d%%)" % round(scale/10)
241 def special(self
, s
):
242 x
= self
.pos
[_POS_H
] * self
.pyxconv
243 y
= -self
.pos
[_POS_V
] * self
.pyxconv
245 self
.debugfile
.write("%d: xxx '%s'\n" % (self
.filepos
, s
))
246 if not s
.startswith("PyX:"):
247 warnings
.warn("ignoring special '%s'" % s
)
250 # it is in general not safe to continue using the currently active font because
251 # the specials may involve some gsave/grestore operations
254 command
, args
= s
[4:].split()[0], s
[4:].split()[1:]
255 if command
== "color_begin":
256 if args
[0] == "cmyk":
257 c
= color
.cmyk(float(args
[1]), float(args
[2]), float(args
[3]), float(args
[4]))
258 elif args
[0] == "gray":
259 c
= color
.gray(float(args
[1]))
260 elif args
[0] == "hsb":
261 c
= color
.hsb(float(args
[1]), float(args
[2]), float(args
[3]))
262 elif args
[0] == "rgb":
263 c
= color
.rgb(float(args
[1]), float(args
[2]), float(args
[3]))
264 elif args
[0] == "RGB":
265 c
= color
.rgb(int(args
[1])/255.0, int(args
[2])/255.0, int(args
[3])/255.0)
266 elif args
[0] == "texnamed":
268 c
= getattr(color
.cmyk
, args
[1])
269 except AttributeError:
270 raise RuntimeError("unknown TeX color '%s', aborting" % args
[1])
271 elif args
[0] == "pyxcolor":
272 # pyx.color.cmyk.PineGreen or
273 # pyx.color.cmyk(0,0,0,0.0)
274 pat
= re
.compile(r
"(pyx\.)?(color\.)?(?P<model>(cmyk)|(rgb)|(grey)|(gray)|(hsb))[\.]?(?P<arg>.*)")
275 sd
= pat
.match(" ".join(args
[1:]))
278 if sd
["arg"][0] == "(":
279 numpat
= re
.compile(r
"[+-]?((\d+\.\d*)|(\d*\.\d+)|(\d+))([eE][+-]\d+)?")
280 arg
= tuple([float(x
[0]) for x
in numpat
.findall(sd
["arg"])])
282 c
= getattr(color
, sd
["model"])(*arg
)
283 except TypeError or AttributeError:
284 raise RuntimeError("cannot access PyX color '%s' in TeX, aborting" % " ".join(args
[1:]))
287 c
= getattr(getattr(color
, sd
["model"]), sd
["arg"])
288 except AttributeError:
289 raise RuntimeError("cannot access PyX color '%s' in TeX, aborting" % " ".join(args
[1:]))
291 raise RuntimeError("cannot access PyX color '%s' in TeX, aborting" % " ".join(args
[1:]))
293 raise RuntimeError("color model '%s' cannot be handled by PyX, aborting" % args
[0])
294 self
.actpage
.insert(_savecolor())
295 self
.actpage
.insert(c
)
296 elif command
== "color_end":
297 self
.actpage
.insert(_restorecolor())
298 elif command
== "rotate_begin":
299 self
.actpage
.insert(_savetrafo())
300 self
.actpage
.insert(trafo
.rotate_pt(float(args
[0]), x
, y
))
301 elif command
== "rotate_end":
302 self
.actpage
.insert(_restoretrafo())
303 elif command
== "scale_begin":
304 self
.actpage
.insert(_savetrafo())
305 self
.actpage
.insert(trafo
.scale_pt(float(args
[0]), float(args
[1]), x
, y
))
306 elif command
== "scale_end":
307 self
.actpage
.insert(_restoretrafo())
308 elif command
== "epsinclude":
312 name
, value
= arg
.split("=")
313 argdict
[name
] = value
315 # construct kwargs for epsfile constructor
317 epskwargs
["filename"] = argdict
["file"]
318 epskwargs
["bbox"] = bbox
.bbox_pt(float(argdict
["llx"]), float(argdict
["lly"]),
319 float(argdict
["urx"]), float(argdict
["ury"]))
320 if argdict
.has_key("width"):
321 epskwargs
["width"] = float(argdict
["width"]) * unit
.t_pt
322 if argdict
.has_key("height"):
323 epskwargs
["height"] = float(argdict
["height"]) * unit
.t_pt
324 if argdict
.has_key("clip"):
325 epskwargs
["clip"] = int(argdict
["clip"])
326 self
.actpage
.insert(epsfile
.epsfile(x
* unit
.t_pt
, y
* unit
.t_pt
, **epskwargs
))
327 elif command
== "marker":
329 raise RuntimeError("marker contains spaces")
331 if c
not in string
.digits
+ string
.letters
+ "@":
332 raise RuntimeError("marker contains invalid characters")
333 if self
.actpage
.markers
.has_key(args
[0]):
334 raise RuntimeError("marker name occurred several times")
335 self
.actpage
.markers
[args
[0]] = x
* unit
.t_pt
, y
* unit
.t_pt
337 raise RuntimeError("unknown PyX special '%s', aborting" % command
)
339 # routines for pushing and popping different dvi chunks on the reader
341 def _push_dvistring(self
, dvi
, fonts
, afterpos
, fontsize
):
342 """ push dvi string with defined fonts on top of reader
343 stack. Every positions gets scaled relatively by the factor
344 scale. After the interpreting of the dvi chunk has been finished,
345 continue with self.pos=afterpos. The designsize of the virtual
346 font is passed as a fix_word
351 # self.debugfile.write("executing new dvi chunk\n")
352 self
.debugstack
.append(self
.debug
)
355 self
.statestack
.append((self
.file, self
.fonts
, self
.activefont
, afterpos
, self
.stack
, self
.pyxconv
, self
.tfmconv
))
357 # units in vf files are relative to the size of the font and given as fix_words
358 # which can be converted to floats by diving by 2**20
359 oldpyxconv
= self
.pyxconv
360 self
.pyxconv
= fontsize
/2**20
361 rescale
= self
.pyxconv
/oldpyxconv
363 self
.file = reader
.stringreader(dvi
)
368 # rescale self.pos in order to be consistent with the new scaling
369 self
.pos
= map(lambda x
, rescale
=rescale
:1.0*x
/rescale
, self
.pos
)
371 # since tfmconv converts from tfm units to dvi units, rescale it as well
372 self
.tfmconv
/= rescale
376 def _pop_dvistring(self
):
379 # self.debugfile.write("finished executing dvi chunk\n")
380 self
.debug
= self
.debugstack
.pop()
383 self
.file, self
.fonts
, self
.activefont
, self
.pos
, self
.stack
, self
.pyxconv
, self
.tfmconv
= self
.statestack
.pop()
385 # routines corresponding to the different reader states of the dvi maschine
390 self
.filepos
= afile
.tell()
391 cmd
= afile
.readuchar()
394 elif cmd
== _DVI_PRE
:
395 if afile
.readuchar() != _DVI_VERSION
: raise DVIError
396 num
= afile
.readuint32()
397 den
= afile
.readuint32()
398 self
.mag
= afile
.readuint32()
400 # For the interpretation of the lengths in dvi and tfm files,
401 # three conversion factors are relevant:
402 # - self.tfmconv: tfm units -> dvi units
403 # - self.pyxconv: dvi units -> (PostScript) points
404 # - self.conv: dvi units -> pixels
405 self
.tfmconv
= (25400000.0/num
)*(den
/473628672.0)/16.0
407 # calculate conv as described in the DVIType docu using
408 # a given resolution in dpi
409 self
.resolution
= 300.0
410 self
.conv
= (num
/254000.0)*(self
.resolution
/den
)
412 # self.pyxconv is the conversion factor from the dvi units
413 # to (PostScript) points. It consists of
414 # - self.mag/1000.0: magstep scaling
415 # - self.conv: conversion from dvi units to pixels
416 # - 1/self.resolution: conversion from pixels to inch
417 # - 72 : conversion from inch to points
418 self
.pyxconv
= self
.mag
/1000.0*self
.conv
/self
.resolution
*72
420 comment
= afile
.read(afile
.readuchar())
425 def readpage(self
, pageid
=None):
426 """ reads a page from the dvi file
428 This routine reads a page from the dvi file which is
429 returned as a canvas. When there is no page left in the
430 dvifile, None is returned and the file is closed properly."""
433 self
.filepos
= self
.file.tell()
434 cmd
= self
.file.readuchar()
437 elif cmd
== _DVI_BOP
:
438 ispageid
= [self
.file.readuint32() for i
in range(10)]
439 if pageid
is not None and ispageid
!= pageid
:
440 raise DVIError("invalid pageid")
442 self
.debugfile
.write("%d: beginning of page %i\n" % (self
.filepos
, ispageid
[0]))
443 self
.file.readuint32()
445 elif cmd
== _DVI_POST
:
447 return None # nothing left
451 self
.actpage
= canvas
.canvas()
452 self
.actpage
.markers
= {}
453 self
.pos
= [0, 0, 0, 0, 0, 0]
455 # tuple (hpos, vpos, codepoints) to be output, or None if no output is pending
456 self
.activetext
= None
460 self
.filepos
= afile
.tell()
462 cmd
= afile
.readuchar()
464 # we most probably (if the dvi file is not corrupt) hit the end of a dvi chunk,
465 # so we have to continue with the rest of the dvi file
466 self
._pop
_dvistring
()
470 if cmd
>= _DVI_CHARMIN
and cmd
<= _DVI_CHARMAX
:
472 elif cmd
>= _DVI_SET1234
and cmd
< _DVI_SET1234
+ 4:
473 self
.putchar(afile
.readint(cmd
- _DVI_SET1234
+ 1), id1234
=cmd
-_DVI_SET1234
+1)
474 elif cmd
== _DVI_SETRULE
:
475 self
.putrule(afile
.readint32(), afile
.readint32())
476 elif cmd
>= _DVI_PUT1234
and cmd
< _DVI_PUT1234
+ 4:
477 self
.putchar(afile
.readint(cmd
- _DVI_PUT1234
+ 1), advancepos
=0, id1234
=cmd
-_DVI_SET1234
+1)
478 elif cmd
== _DVI_PUTRULE
:
479 self
.putrule(afile
.readint32(), afile
.readint32(), 0)
480 elif cmd
== _DVI_EOP
:
483 self
.debugfile
.write("%d: eop\n \n" % self
.filepos
)
485 elif cmd
== _DVI_PUSH
:
486 self
.stack
.append(list(self
.pos
))
488 self
.debugfile
.write("%s: push\n"
489 "level %d:(h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=???,vv=???)\n" %
490 ((self
.filepos
, len(self
.stack
)-1) + tuple(self
.pos
)))
491 elif cmd
== _DVI_POP
:
493 self
.pos
= self
.stack
.pop()
495 self
.debugfile
.write("%s: pop\n"
496 "level %d:(h=%d,v=%d,w=%d,x=%d,y=%d,z=%d,hh=???,vv=???)\n" %
497 ((self
.filepos
, len(self
.stack
)) + tuple(self
.pos
)))
498 elif cmd
>= _DVI_RIGHT1234
and cmd
< _DVI_RIGHT1234
+ 4:
500 dh
= afile
.readint(cmd
- _DVI_RIGHT1234
+ 1, 1)
502 self
.debugfile
.write("%d: right%d %d h:=%d%+d=%d, hh:=???\n" %
504 cmd
- _DVI_RIGHT1234
+ 1,
508 self
.pos
[_POS_H
]+dh
))
509 self
.pos
[_POS_H
] += dh
513 self
.debugfile
.write("%d: w0 %d h:=%d%+d=%d, hh:=???\n" %
518 self
.pos
[_POS_H
]+self
.pos
[_POS_W
]))
519 self
.pos
[_POS_H
] += self
.pos
[_POS_W
]
520 elif cmd
>= _DVI_W1234
and cmd
< _DVI_W1234
+ 4:
522 self
.pos
[_POS_W
] = afile
.readint(cmd
- _DVI_W1234
+ 1, 1)
524 self
.debugfile
.write("%d: w%d %d h:=%d%+d=%d, hh:=???\n" %
526 cmd
- _DVI_W1234
+ 1,
530 self
.pos
[_POS_H
]+self
.pos
[_POS_W
]))
531 self
.pos
[_POS_H
] += self
.pos
[_POS_W
]
535 self
.debugfile
.write("%d: x0 %d h:=%d%+d=%d, hh:=???\n" %
540 self
.pos
[_POS_H
]+self
.pos
[_POS_X
]))
541 self
.pos
[_POS_H
] += self
.pos
[_POS_X
]
542 elif cmd
>= _DVI_X1234
and cmd
< _DVI_X1234
+ 4:
544 self
.pos
[_POS_X
] = afile
.readint(cmd
- _DVI_X1234
+ 1, 1)
546 self
.debugfile
.write("%d: x%d %d h:=%d%+d=%d, hh:=???\n" %
548 cmd
- _DVI_X1234
+ 1,
552 self
.pos
[_POS_H
]+self
.pos
[_POS_X
]))
553 self
.pos
[_POS_H
] += self
.pos
[_POS_X
]
554 elif cmd
>= _DVI_DOWN1234
and cmd
< _DVI_DOWN1234
+ 4:
556 dv
= afile
.readint(cmd
- _DVI_DOWN1234
+ 1, 1)
558 self
.debugfile
.write("%d: down%d %d v:=%d%+d=%d, vv:=???\n" %
560 cmd
- _DVI_DOWN1234
+ 1,
564 self
.pos
[_POS_V
]+dv
))
565 self
.pos
[_POS_V
] += dv
569 self
.debugfile
.write("%d: y0 %d v:=%d%+d=%d, vv:=???\n" %
574 self
.pos
[_POS_V
]+self
.pos
[_POS_Y
]))
575 self
.pos
[_POS_V
] += self
.pos
[_POS_Y
]
576 elif cmd
>= _DVI_Y1234
and cmd
< _DVI_Y1234
+ 4:
578 self
.pos
[_POS_Y
] = afile
.readint(cmd
- _DVI_Y1234
+ 1, 1)
580 self
.debugfile
.write("%d: y%d %d v:=%d%+d=%d, vv:=???\n" %
582 cmd
- _DVI_Y1234
+ 1,
586 self
.pos
[_POS_V
]+self
.pos
[_POS_Y
]))
587 self
.pos
[_POS_V
] += self
.pos
[_POS_Y
]
591 self
.debugfile
.write("%d: z0 %d v:=%d%+d=%d, vv:=???\n" %
596 self
.pos
[_POS_V
]+self
.pos
[_POS_Z
]))
597 self
.pos
[_POS_V
] += self
.pos
[_POS_Z
]
598 elif cmd
>= _DVI_Z1234
and cmd
< _DVI_Z1234
+ 4:
600 self
.pos
[_POS_Z
] = afile
.readint(cmd
- _DVI_Z1234
+ 1, 1)
602 self
.debugfile
.write("%d: z%d %d v:=%d%+d=%d, vv:=???\n" %
604 cmd
- _DVI_Z1234
+ 1,
608 self
.pos
[_POS_V
]+self
.pos
[_POS_Z
]))
609 self
.pos
[_POS_V
] += self
.pos
[_POS_Z
]
610 elif cmd
>= _DVI_FNTNUMMIN
and cmd
<= _DVI_FNTNUMMAX
:
611 self
.usefont(cmd
- _DVI_FNTNUMMIN
, 0)
612 elif cmd
>= _DVI_FNT1234
and cmd
< _DVI_FNT1234
+ 4:
613 # note that according to the DVI docs, for four byte font numbers,
614 # the font number is signed. Don't ask why!
615 fntnum
= afile
.readint(cmd
- _DVI_FNT1234
+ 1, cmd
== _DVI_FNT1234
+ 3)
616 self
.usefont(fntnum
, id1234
=cmd
-_DVI_FNT1234
+1)
617 elif cmd
>= _DVI_SPECIAL1234
and cmd
< _DVI_SPECIAL1234
+ 4:
618 self
.special(afile
.read(afile
.readint(cmd
- _DVI_SPECIAL1234
+ 1)))
619 elif cmd
>= _DVI_FNTDEF1234
and cmd
< _DVI_FNTDEF1234
+ 4:
620 if cmd
== _DVI_FNTDEF1234
:
621 num
= afile
.readuchar()
622 elif cmd
== _DVI_FNTDEF1234
+1:
623 num
= afile
.readuint16()
624 elif cmd
== _DVI_FNTDEF1234
+2:
625 num
= afile
.readuint24()
626 elif cmd
== _DVI_FNTDEF1234
+3:
627 # Cool, here we have according to docu a signed int. Why?
628 num
= afile
.readint32()
629 self
.definefont(cmd
-_DVI_FNTDEF1234
+1,
634 afile
.read(afile
.readuchar()+afile
.readuchar()))