1 # -*- encoding: utf-8 -*-
4 # Copyright (C) 2005-2011 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2005-2011 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
24 from . import bbox
, pswriter
, pdfwriter
, svgwriter
, trafo
, style
, unit
26 logger
= logging
.getLogger("pyx")
30 def __init__(self
, width
, height
, name
=None):
35 paperformat
.A5
= paperformat(148.5 * unit
.t_mm
, 210 * unit
.t_mm
, "A5")
36 paperformat
.A4
= paperformat(210 * unit
.t_mm
, 297 * unit
.t_mm
, "A4")
37 paperformat
.A3
= paperformat(297 * unit
.t_mm
, 420 * unit
.t_mm
, "A3")
38 paperformat
.A2
= paperformat(420 * unit
.t_mm
, 594 * unit
.t_mm
, "A2")
39 paperformat
.A1
= paperformat(594 * unit
.t_mm
, 840 * unit
.t_mm
, "A1")
40 paperformat
.A0
= paperformat(840 * unit
.t_mm
, 1188 * unit
.t_mm
, "A0")
41 paperformat
.A0b
= paperformat(910 * unit
.t_mm
, 1370 * unit
.t_mm
, None) # dedicated to our friends in Augsburg
42 paperformat
.Letter
= paperformat(8.5 * unit
.t_inch
, 11 * unit
.t_inch
, "Letter")
43 paperformat
.Legal
= paperformat(8.5 * unit
.t_inch
, 14 * unit
.t_inch
, "Legal")
45 def _paperformatfromstring(name
):
46 return getattr(paperformat
, name
.capitalize())
51 def __init__(self
, canvas
, pagename
=None, paperformat
=None, rotated
=0, centered
=1, fittosize
=0,
52 margin
=1*unit
.t_cm
, bboxenlarge
=1*unit
.t_pt
, bbox
=None):
54 self
.pagename
= pagename
55 # support for deprecated string specification of paper formats
59 self
.paperformat
= paperformat
61 self
.paperformat
= _paperformatfromstring(paperformat
)
62 logger
.warning("specification of paperformat by string is deprecated, use document.paperformat.%s instead" % paperformat
.capitalize())
64 self
.rotated
= rotated
65 self
.centered
= centered
66 self
.fittosize
= fittosize
68 self
.bboxenlarge
= bboxenlarge
71 def _process(self
, processMethod
, contentfile
, writer
, context
, registry
, bbox
):
72 # usually, it is the bbox of the canvas enlarged by self.bboxenlarge, but
73 # it might be a different bbox as specified in the page constructor
76 bbox
.set(self
.pagebbox
)
78 bbox
.set(self
.canvas
.bbox()) # this bbox is not accurate
79 bbox
.enlarge(self
.bboxenlarge
)
81 # check whether we expect a page trafo and use a temporary canvas to insert the
83 if self
.paperformat
and (self
.rotated
or self
.centered
or self
.fittosize
) and bbox
:
84 # calculate the pagetrafo
85 paperwidth
, paperheight
= self
.paperformat
.width
, self
.paperformat
.height
87 # center (optionally rotated) output on page
89 pagetrafo
= trafo
.rotate(90).translated(paperwidth
, 0)
90 if self
.centered
or self
.fittosize
:
91 if not self
.fittosize
and (bbox
.height() > paperwidth
or bbox
.width() > paperheight
):
92 logger
.warning("content exceeds the papersize")
93 pagetrafo
= pagetrafo
.translated(-0.5*(paperwidth
- bbox
.height()) + bbox
.bottom(),
94 0.5*(paperheight
- bbox
.width()) - bbox
.left())
96 if not self
.fittosize
and (bbox
.width() > paperwidth
or bbox
.height() > paperheight
):
97 logger
.warning("content exceeds the papersize")
98 pagetrafo
= trafo
.translate(0.5*(paperwidth
- bbox
.width()) - bbox
.left(),
99 0.5*(paperheight
- bbox
.height()) - bbox
.bottom())
103 if 2*self
.margin
> paperwidth
or 2*self
.margin
> paperheight
:
104 raise ValueError("Margins too broad for selected paperformat. Aborting.")
106 paperwidth
-= 2 * self
.margin
107 paperheight
-= 2 * self
.margin
109 # scale output to pagesize - margins
111 sfactor
= min(unit
.topt(paperheight
)/bbox
.width_pt(), unit
.topt(paperwidth
)/bbox
.height_pt())
113 sfactor
= min(unit
.topt(paperwidth
)/bbox
.width_pt(), unit
.topt(paperheight
)/bbox
.height_pt())
115 pagetrafo
= pagetrafo
.scaled(sfactor
, sfactor
, self
.margin
+ 0.5*paperwidth
, self
.margin
+ 0.5*paperheight
)
117 bbox
.transform(pagetrafo
)
118 from . import canvas
as canvasmodule
119 cc
= canvasmodule
.canvas()
120 cc
.insert(self
.canvas
, [pagetrafo
])
124 if processMethod
!= "processSVG":
125 # for SVG we write the pyx defaults as part of the svg node attributes in the writer
126 getattr(style
.linewidth
.normal
, processMethod
)(contentfile
, writer
, context
, registry
)
128 bbox
= bbox
.copy() # don't alter the bbox provided to the constructor -> use a copy
129 getattr(cc
, processMethod
)(contentfile
, writer
, context
, registry
, bbox
)
131 def processPS(self
, *args
):
132 self
._process
("processPS", *args
)
134 def processPDF(self
, *args
):
135 self
._process
("processPDF", *args
)
137 def processSVG(self
, *args
):
138 self
._process
("processSVG", *args
)
143 def __init__(self
, f
):
149 def __exit__(self
, type, value
, tb
):
153 def _outputstream(file, suffix
):
155 if not sys
.argv
[0].endswith(".py"):
156 raise RuntimeError("could not auto-guess filename")
157 return open("%s.%s" % (sys
.argv
[0][:-3], suffix
), "wb")
159 return _noclose(sys
.stdout
.buffer)
163 if not file.endswith(".%s" % suffix
):
164 return open("%s.%s" % (file, suffix
), "wb")
165 return open(file, "wb")
167 return _noclose(file)
172 """holds a collection of page instances which are output as pages of a document"""
174 def __init__(self
, pages
=None):
180 def append(self
, page
):
181 self
.pages
.append(page
)
183 def writeEPSfile(self
, file=None, **kwargs
):
184 with
_outputstream(file, "eps") as f
:
185 pswriter
.EPSwriter(self
, f
, **kwargs
)
187 def writePSfile(self
, file=None, **kwargs
):
188 with
_outputstream(file, "ps") as f
:
189 pswriter
.PSwriter(self
, f
, **kwargs
)
191 def writePDFfile(self
, file=None, **kwargs
):
192 with
_outputstream(file, "pdf") as f
:
193 pdfwriter
.PDFwriter(self
, f
, **kwargs
)
195 def writeSVGfile(self
, file=None, **kwargs
):
196 with
_outputstream(file, "svg") as f
:
197 svgwriter
.SVGwriter(self
, f
, **kwargs
)
199 def writetofile(self
, filename
, **kwargs
):
200 for suffix
, method
in [("eps", pswriter
.EPSwriter
),
201 ("ps", pswriter
.PSwriter
),
202 ("pdf", pdfwriter
.PDFwriter
),
203 ("svg", svgwriter
.SVGwriter
)]:
204 if filename
.endswith(".{}".format(suffix
)):
205 with
open(filename
, "wb") as f
:
206 method(self
, f
, **kwargs
)
208 raise ValueError("unknown file extension")