add support for virtual fonts in virtual fonts
[PyX.git] / pyx / dvi / vffile.py
blob79f8c71e847efab5f0a469a3f97968e28555157a
1 # -*- encoding: utf-8 -*-
4 # Copyright (C) 2002-2007 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2002-2007 André Wobst <wobsta@users.sourceforge.net>
7 # This file is part of PyX (http://pyx.sourceforge.net/).
9 # PyX is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 2 of the License, or
12 # (at your option) any later version.
14 # PyX is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with PyX; if not, write to the Free Software
21 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 from pyx import reader
25 _VF_LONG_CHAR = 242 # character packet (long version)
26 _VF_FNTDEF1234 = 243 # font definition
27 _VF_PRE = 247 # preamble
28 _VF_POST = 248 # postamble
29 _VF_ID = 202 # VF id byte
31 class VFError(Exception): pass
33 class vffile:
35 def __init__(self, file, scale, tfmconv, pyxconv, debug=0):
36 self.scale = scale
37 self.tfmconv = tfmconv
38 self.pyxconv = pyxconv
39 self.debug = debug
40 self.fonts = {} # used fonts
41 self.widths = {} # widths of defined chars
42 self.chardefs = {} # dvi chunks for defined chars
44 afile = reader.bytesreader(file.read())
46 cmd = afile.readuchar()
47 if cmd == _VF_PRE:
48 if afile.readuchar() != _VF_ID: raise VFError
49 comment = afile.read(afile.readuchar())
50 self.cs = afile.readuint32()
51 self.ds = afile.readuint32()
52 else:
53 raise VFError
55 while True:
56 cmd = afile.readuchar()
57 if cmd >= _VF_FNTDEF1234 and cmd < _VF_FNTDEF1234 + 4:
58 # font definition
59 if cmd == _VF_FNTDEF1234:
60 num = afile.readuchar()
61 elif cmd == _VF_FNTDEF1234+1:
62 num = afile.readuint16()
63 elif cmd == _VF_FNTDEF1234+2:
64 num = afile.readuint24()
65 elif cmd == _VF_FNTDEF1234+3:
66 num = afile.readint32()
67 c = afile.readint32()
68 s = afile.readint32() # relative scaling used for font (fix_word)
69 d = afile.readint32() # design size of font
70 fontname = afile.read(afile.readuchar() + afile.readuchar()).decode("ascii")
72 # rescaled size of font: s is relative to the scaling
73 # of the virtual font itself. Note that realscale has
74 # to be a fix_word (like s)
75 # XXX: check rounding
76 reals = int(round(self.scale * (16*self.ds/16777216) * s))
78 # print ("defining font %s -- VF scale: %g, VF design size: %d, relative font size: %d => real size: %d" %
79 # (fontname, self.scale, self.ds, s, reals)
80 # )
82 from pyx import config
83 from . import texfont
84 try:
85 with config.open(fontname, [config.format.vf]) as fontfile:
86 self.fonts[num] = texfont.virtualfont(fontname, fontfile, c, reals, d, self.tfmconv, self.pyxconv, self.debug>1)
87 except EnvironmentError:
88 self.fonts[num] = texfont.TeXfont(fontname, c, reals, d, self.tfmconv, self.pyxconv, self.debug>1)
89 elif cmd == _VF_LONG_CHAR:
90 # character packet (long form)
91 pl = afile.readuint32() # packet length
92 cc = afile.readuint32() # char code (assumed unsigned, but anyhow only 0 <= cc < 255 is actually used)
93 tfm = afile.readuint24() # character width
94 dvi = afile.read(pl) # dvi code of character
95 self.widths[cc] = tfm
96 self.chardefs[cc] = dvi
97 elif cmd < _VF_LONG_CHAR:
98 # character packet (short form)
99 cc = afile.readuchar() # char code
100 tfm = afile.readuint24() # character width
101 dvi = afile.read(cmd)
102 self.widths[cc] = tfm
103 self.chardefs[cc] = dvi
104 elif cmd == _VF_POST:
105 break
106 else:
107 raise VFError
109 def getfonts(self):
110 return self.fonts
112 def getchar(self, cc):
113 return self.chardefs[cc]