107
86
def output(self, file, writer, registry):
108
file.write("%%%%BeginRessource: %s\n" % self.id)
87
file.write("%%%%BeginResource: %s\n" % self.id)
109
88
file.write("%(body)s /%(id)s exch def\n" % self.__dict__)
110
file.write("%%EndRessource\n")
115
def __init__(self, font, chars, registry):
117
registry.add(PSfontfile(font.basefontname,
121
if font.encoding and font.slant:
123
# do first the reencoding and then the slanting:
124
enc_basename, enc_finalname = font.basefontname, font.encname
125
slt_basename, slt_finalname = tfont.encname, font.name
127
enc_basename, enc_finalname = font.basefontname, font.name
129
slt_basename, slt_finalname = font.basefontname, font.name
132
registry.add(_ReEncodeFont)
133
registry.add(PSfontencoding(font.encoding))
134
registry.add(PSfontreencoding(enc_finalname, enc_basename, font.encoding.name))
137
# we need the current fontmatrix in order to manipulate it:
138
# for this we need to re-read the fontfile as below in
140
# XXX Is there a better way to do this?
141
t = trafo.trafo_pt(matrix=((1, font.slant), (0, 1)))
143
# for the builtin fonts, we assume a trivial fontmatrix
144
import font.t1font as t1fontmodule
145
t1font = t1fontmodule.T1pfbfont(font.filename)
146
m = t1font.fontmatrixpattern.search(t1font.data1)
147
m11, m12, m21, m22, v1, v2 = map(float, m.groups()[:6])
148
t *= trafo.trafo_pt(matrix=((m11, m12), (m21, m22)), vector=(v1, v2))
150
raise NotImplementedError(
151
"cannot slant unembedded fonts -- try to include \"download35.map\" in fontmaps")
152
registry.add(PSfontslanting(slt_finalname, slt_basename, t.__str__()))
155
class PSfontfile(PSresource):
157
""" PostScript font definition included in the prolog """
159
def __init__(self, name, filename, encoding, chars):
160
""" include type 1 font defined by the following parameters
162
- name: name of the PostScript font
163
- filename: name (without path) of file containing the font definition
164
- encfilename: name (without path) of file containing used encoding of font
165
or None (if no encoding file used)
166
- chars: character list to fill usedchars
170
# Note that here we only need the encoding for selecting the used glyphs!
172
self.type = "fontfile"
173
self.id = self.name = name
174
self.filename = filename
176
self.encodingfilename = None
178
self.encodingfilename = encoding.filename
181
self.usedchars[char] = 1
185
def merge(self, other):
186
if self.encodingfilename == other.encodingfilename:
187
self.usedchars.update(other.usedchars)
189
# TODO: need to resolve the encoding when several encodings are in the play
192
def output(self, file, writer, registry):
194
font = font.t1font.T1pfbfont(self.filename)
196
file.write("%%%%BeginFont: %s\n" % self.name)
197
# file.write("%%Included glyphs: %s\n" % " ".join(usedglyphs))
199
# XXX: access to the encoding file
200
if self.encodingfilename:
201
encodingfile = type1font.encodingfile(self.encodingfilename, self.encodingfilename)
202
usedglyphs = dict([(encodingfile.decode(char)[1:], 1) for char in self.usedchars.keys()])
205
usedglyphs = dict([(font.encoding.decode(char), 1) for char in self.usedchars.keys()])
206
strippedfont = font.getstrippedfont(usedglyphs)
209
strippedfont.outputPS(file, writer)
210
file.write("\n%%EndFont\n")
213
class PSfontencoding(PSresource):
215
""" PostScript font encoding vector included in the prolog """
217
def __init__(self, encoding):
218
""" include font encoding vector specified by encoding """
220
self.type = "fontencoding"
221
self.id = encoding.name
222
self.encoding = encoding
224
def output(self, file, writer, registry):
225
encodingfile = type1font.encodingfile(self.encoding.name, self.encoding.filename)
226
encodingfile.outputPS(file, writer)
229
class PSfontslanting(PSresource):
231
""" PostScript font slanting directive included in the prolog """
233
def __init__(self, fontname, basefontname, matrixstring):
234
""" include transformed font directive specified by
236
- fontname: PostScript FontName of the new slanted font
237
- basefontname: PostScript FontName of the original font
238
- slant: the value of slanting
241
self.type = "fontslanting"
242
self.id = self.fontname = fontname
243
self.basefontname = basefontname
244
self.matrixstring = matrixstring
246
def output(self, file, writer, registry):
247
file.write("%%%%BeginProcSet: %s\n" % self.fontname)
248
file.write("/%s findfont\n" % self.basefontname)
249
file.write("dup length dict begin\n")
250
file.write("{ 1 index /FID ne {def} {pop pop} ifelse } forall\n")
251
file.write("/FontMatrix %s readonly def\n" % self.matrixstring)
252
file.write("currentdict\n")
254
file.write("/%s exch definefont pop\n" % self.fontname)
255
file.write("%%EndProcSet\n")
257
class PSfontreencoding(PSresource):
259
""" PostScript font re-encoding directive included in the prolog """
261
def __init__(self, fontname, basefontname, encodingname):
262
""" include font re-encoding directive specified by
264
- fontname: PostScript FontName of the new reencoded font
265
- basefontname: PostScript FontName of the original font
266
- encname: name of the encoding
268
Before being able to reencode a font, you have to include the
269
encoding via a fontencoding prolog item with name=encname
273
self.type = "fontreencoding"
274
self.id = self.fontname = fontname
275
self.basefontname = basefontname
276
self.encodingname = encodingname
278
def output(self, file, writer, registry):
279
file.write("%%%%BeginProcSet: %s\n" % self.fontname)
280
file.write("/%s /%s %s ReEncodeFont\n" % (self.basefontname, self.fontname, self.encodingname))
281
file.write("%%EndProcSet\n")
284
_ReEncodeFont = PSdefinition("ReEncodeFont", """{
287
/newencoding exch def
288
/newfontname exch def
289
/basefontname exch def
290
/basefontdict basefontname findfont def
291
/newfontdict basefontdict maxlength dict def
293
exch dup dup /FID ne exch /Encoding ne and
294
{ exch newfontdict 3 1 roll put }
298
newfontdict /FontName newfontname put
299
newfontdict /Encoding newencoding put
300
newfontname newfontdict definefont pop
307
def __init__(self, document, file):
89
file.write("%%EndResource\n")
97
def __init__(self, title=None, strip_fonts=True, text_as_path=False, mesh_as_bitmap=False, mesh_as_bitmap_resolution=300):
100
self.strip_fonts = strip_fonts
101
self.text_as_path = text_as_path
102
self.mesh_as_bitmap = mesh_as_bitmap
103
self.mesh_as_bitmap_resolution = mesh_as_bitmap_resolution
105
# dictionary mapping font names to dictionaries mapping encoding names to encodings
106
# encodings themselves are mappings from glyphnames to codepoints
109
def writeinfo(self, file):
110
file.write("%%%%Creator: PyX %s\n" % version.version)
111
if self.title is not None:
112
file.write("%%%%Title: %s\n" % self.title)
113
file.write("%%%%CreationDate: %s\n" %
114
time.asctime(time.localtime(time.time())))
116
def getfontmap(self):
117
if self._fontmap is None:
118
# late import due to cyclic dependency
119
from pyx.dvi import mapfile
120
fontmapfiles = config.getlist("text", "psfontmaps", ["psfonts.map"])
121
self._fontmap = mapfile.readfontmap(fontmapfiles)
125
class EPSwriter(_PSwriter):
127
def __init__(self, document, file, **kwargs):
128
_PSwriter.__init__(self, **kwargs)
308
130
if len(document.pages) != 1:
309
131
raise ValueError("EPS file can be constructed out of a single page document only")
310
132
page = document.pages[0]
311
133
canvas = page.canvas
317
if not filename.endswith(".eps"):
320
file = open(filename, "w")
322
raise IOError("cannot open output file")
326
135
pagefile = cStringIO.StringIO()
327
136
registry = PSregistry()
328
137
acontext = context()