adjust some copyright dates according to diffs to previous versions and recent work
[PyX.git] / pyx / document.py
blob9b7e26e0556e3aca8e1a970218e9babca467bc8c
1 # -*- coding: ISO-8859-1 -*-
4 # Copyright (C) 2005-2006 Jörg Lehmann <joergl@users.sourceforge.net>
5 # Copyright (C) 2005-2006 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 import cStringIO, warnings
24 import bbox, pswriter, pdfwriter, trafo, style, unit
27 class paperformat:
29 def __init__(self, width, height, name=None):
30 self.width = width
31 self.height = height
32 self.name = name
34 paperformat.A4 = paperformat(210 * unit.t_mm, 297 * unit.t_mm, "A4")
35 paperformat.A3 = paperformat(297 * unit.t_mm, 420 * unit.t_mm, "A3")
36 paperformat.A2 = paperformat(420 * unit.t_mm, 594 * unit.t_mm, "A2")
37 paperformat.A1 = paperformat(594 * unit.t_mm, 840 * unit.t_mm, "A1")
38 paperformat.A0 = paperformat(840 * unit.t_mm, 1188 * unit.t_mm, "A0")
39 paperformat.A0b = paperformat(910 * unit.t_mm, 1370 * unit.t_mm, None) # dedicated to our friends in Augsburg
40 paperformat.Letter = paperformat(8.5 * unit.t_inch, 11 * unit.t_inch, "Letter")
41 paperformat.Legal = paperformat(8.5 * unit.t_inch, 14 * unit.t_inch, "Legal")
43 def _paperformatfromstring(name):
44 return getattr(paperformat, name.capitalize())
47 class page:
49 def __init__(self, canvas, pagename=None, paperformat=None, rotated=0, centered=1, fittosize=0,
50 margin=1*unit.t_cm, bboxenlarge=1*unit.t_pt, bbox=None):
51 self.canvas = canvas
52 self.pagename = pagename
53 # support for depricated string specification of paper formats
54 try:
55 paperformat + ""
56 except:
57 self.paperformat = paperformat
58 else:
59 self.paperformat = _paperformatfromstring(paperformat)
60 warnings.warn("specification of paperformat by string is deprecated, use document.paperformat.%s instead" % paperformat.capitalize(), DeprecationWarning)
62 self.rotated = rotated
63 self.centered = centered
64 self.fittosize = fittosize
65 self.margin = margin
66 self.bboxenlarge = bboxenlarge
67 self.pagebbox = bbox
69 def _process(self, processMethod, contentfile, writer, context, registry, bbox):
70 assert not bbox
72 # check whether we expect a page trafo and use a temporary canvasfile to insert the
73 # pagetrafo in front after the bbox was calculated
74 expectpagetrafo = self.paperformat and (self.rotated or self.centered or self.fittosize)
75 if expectpagetrafo:
76 canvasfile = cStringIO.StringIO()
77 else:
78 canvasfile = contentfile
80 getattr(style.linewidth.normal, processMethod)(canvasfile, writer, context, registry, bbox)
81 getattr(self.canvas, processMethod)(canvasfile, writer, context, registry, bbox)
83 # usually its the bbox of the canvas enlarged by self.bboxenlarge, but
84 # it might be a different bbox as specified in the page constructor
85 if self.pagebbox:
86 bbox.set(self.pagebbox)
87 elif bbox:
88 bbox.enlarge(self.bboxenlarge)
90 if expectpagetrafo:
92 if bbox:
93 # calculate the pagetrafo
94 paperwidth, paperheight = self.paperformat.width, self.paperformat.height
96 # center (optionally rotated) output on page
97 if self.rotated:
98 pagetrafo = trafo.rotate(90).translated(paperwidth, 0)
99 if self.centered or self.fittosize:
100 if not self.fittosize and (bbox.height() > paperwidth or bbox.width() > paperheight):
101 warnings.warn("content exceeds the papersize")
102 pagetrafo = pagetrafo.translated(-0.5*(paperwidth - bbox.height()) + bbox.bottom(),
103 0.5*(paperheight - bbox.width()) - bbox.left())
104 else:
105 if not self.fittosize and (bbox.width() > paperwidth or bbox.height() > paperheight):
106 warnings.warn("content exceeds the papersize")
107 pagetrafo = trafo.translate(0.5*(paperwidth - bbox.width()) - bbox.left(),
108 0.5*(paperheight - bbox.height()) - bbox.bottom())
110 if self.fittosize:
112 if 2*self.margin > paperwidth or 2*self.margin > paperheight:
113 raise ValueError("Margins too broad for selected paperformat. Aborting.")
115 paperwidth -= 2 * self.margin
116 paperheight -= 2 * self.margin
118 # scale output to pagesize - margins
119 if self.rotated:
120 sfactor = min(unit.topt(paperheight)/bbox.width_pt(), unit.topt(paperwidth)/bbox.height_pt())
121 else:
122 sfactor = min(unit.topt(paperwidth)/bbox.width_pt(), unit.topt(paperheight)/bbox.height_pt())
124 pagetrafo = pagetrafo.scaled(sfactor, sfactor, self.margin + 0.5*paperwidth, self.margin + 0.5*paperheight)
126 # apply the pagetrafo and write it to the contentfile
127 bbox.transform(pagetrafo)
128 pagetrafofile = cStringIO.StringIO()
129 # context, bbox, registry are just passed as stubs (the trafo should not touch them)
130 getattr(pagetrafo, processMethod)(pagetrafofile, writer, context, registry, bbox)
131 contentfile.write(pagetrafofile.getvalue())
132 pagetrafofile.close()
134 contentfile.write(canvasfile.getvalue())
135 canvasfile.close()
137 def processPS(self, *args):
138 self._process("processPS", *args)
140 def processPDF(self, *args):
141 self._process("processPDF", *args)
144 class document:
146 """holds a collection of page instances which are output as pages of a document"""
148 def __init__(self, pages=[]):
149 self.pages = pages
151 def append(self, page):
152 self.pages.append(page)
154 def writeEPSfile(self, file, *args, **kwargs):
155 pswriter.epswriter(self, file, *args, **kwargs)
157 def writePSfile(self, file, *args, **kwargs):
158 pswriter.pswriter(self, file, *args, **kwargs)
160 def writePDFfile(self, file, *args, **kwargs):
161 pdfwriter.PDFwriter(self, file, *args, **kwargs)
163 def writetofile(self, filename, *args, **kwargs):
164 if filename.endswith(".eps"):
165 self.writeEPSfile(filename, *args, **kwargs)
166 elif filename.endswith(".ps"):
167 self.writePSfile(filename, *args, **kwargs)
168 elif filename.endswith(".pdf"):
169 self.writePDFfile(filename, *args, **kwargs)
170 else:
171 raise ValueError("unknown file extension")