correct the self-intersection in parallel
[PyX/mjg.git] / pyx / document.py
blob51b6645d3cdc46e78138343682f9fd161b990627
1 #!/usr/bin/env python
2 # -*- coding: ISO-8859-1 -*-
5 # Copyright (C) 2005 Jörg Lehmann <joergl@users.sourceforge.net>
6 # Copyright (C) 2005 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 warnings
25 import pswriter, pdfwriter, trafo, unit
28 class paperformat:
30 def __init__(self, width, height, name=None):
31 self.width = width
32 self.height = height
33 self.name = name
35 paperformat.A4 = paperformat(210 * unit.t_mm, 297 * unit.t_mm, "A4")
36 paperformat.A3 = paperformat(297 * unit.t_mm, 420 * unit.t_mm, "A3")
37 paperformat.A2 = paperformat(420 * unit.t_mm, 594 * unit.t_mm, "A2")
38 paperformat.A1 = paperformat(594 * unit.t_mm, 840 * unit.t_mm, "A1")
39 paperformat.A0 = paperformat(840 * unit.t_mm, 1188 * unit.t_mm, "A0")
40 paperformat.A0b = paperformat(910 * unit.t_mm, 1370 * unit.t_mm, None) # dedicated to our friends in Augsburg
41 paperformat.Letter = paperformat(8.5 * unit.t_inch, 11 * unit.t_inch, "Letter")
42 paperformat.Legal = paperformat(8.5 * unit.t_inch, 14 * unit.t_inch, "Legal")
44 def _paperformatfromstring(name):
45 return getattr(paperformat, name.capitalize())
48 class page:
50 def __init__(self, canvas, pagename=None, paperformat=None, rotated=0, centered=1, fittosize=0,
51 margin=1 * unit.t_cm, bboxenlarge=1 * unit.t_pt, bbox=None):
52 self.canvas = canvas
53 self.pagename = pagename
54 # support for depricated string specification of paper formats
55 try:
56 paperformat + ""
57 except:
58 self.paperformat = paperformat
59 else:
60 self.paperformat = _paperformatfromstring(paperformat)
61 warnings.warn("specification of paperformat by string is deprecated, use document.paperformat.%s instead" % paperformat.capitalize(), DeprecationWarning)
63 self.rotated = rotated
64 self.centered = centered
65 self.fittosize = fittosize
66 self.margin = margin
67 self.bboxenlarge = bboxenlarge
68 self.pagebbox = bbox
70 def bbox(self):
71 """ returns the bbox of the page
73 usually its the bbox of the canvas enlarged by self.bboxenlarge, but
74 it might be a different bbox as specified in the page constructor"""
75 if self.pagebbox:
76 bbox = self.pagebbox
77 else:
78 bbox = self.canvas.bbox()
79 if bbox:
80 bbox.enlarge(self.bboxenlarge)
81 return bbox
83 def pagetrafo(self, bbox):
84 """ calculate a trafo which rotates and fits a canvas on the page
86 The canvas extents are described by bbox.
87 """
88 if bbox and self.paperformat and (self.rotated or self.centered or self.fittosize):
89 paperwidth, paperheight = self.paperformat.width, self.paperformat.height
91 # center (optionally rotated) output on page
92 if self.rotated:
93 atrafo = trafo.rotate(90).translated(paperwidth, 0)
94 if self.centered or self.fittosize:
95 atrafo = atrafo.translated(-0.5*(paperwidth - bbox.height()) + bbox.bottom(),
96 0.5*(paperheight - bbox.width()) - bbox.left())
97 else:
98 if self.centered or self.fittosize:
99 atrafo = trafo.trafo()
100 else:
101 return None # no page transformation needed
102 if self.centered or self.fittosize:
103 atrafo = atrafo.translated(0.5*(paperwidth - bbox.width()) - bbox.left(),
104 0.5*(paperheight - bbox.height()) - bbox.bottom())
106 if self.fittosize:
108 if 2*self.margin > paperwidth or 2*self.margin > paperheight:
109 raise ValueError("Margins too broad for selected paperformat. Aborting.")
111 paperwidth -= 2 * self.margin
112 paperheight -= 2 * self.margin
114 # scale output to pagesize - margins
115 if self.rotated:
116 sfactor = min(unit.topt(paperheight)/bbox.width_pt(), unit.topt(paperwidth)/bbox.height_pt())
117 else:
118 sfactor = min(unit.topt(paperwidth)/bbox.width_pt(), unit.topt(paperheight)/bbox.height_pt())
120 atrafo = atrafo.scaled(sfactor, sfactor, self.margin + 0.5*paperwidth, self.margin + 0.5*paperheight)
122 return atrafo
124 return None # no page transformation needed
127 class document:
129 """holds a collection of page instances which are output as pages of a document"""
131 def __init__(self, pages=[]):
132 self.pages = pages
134 def append(self, page):
135 self.pages.append(page)
137 def writeEPSfile(self, filename, *args, **kwargs):
138 pswriter.epswriter(self, filename, *args, **kwargs)
140 def writePSfile(self, filename, *args, **kwargs):
141 pswriter.pswriter(self, filename, *args, **kwargs)
143 def writePDFfile(self, filename, *args, **kwargs):
144 pdfwriter.PDFwriter(self, filename, *args, **kwargs)
146 def writetofile(self, filename, *args, **kwargs):
147 if filename.endswith(".eps"):
148 self.writeEPSfile(filename, *args, **kwargs)
149 elif filename.endswith(".ps"):
150 self.writePSfile(filename, *args, **kwargs)
151 elif filename.endswith(".pdf"):
152 self.writePDFfile(filename, *args, **kwargs)
153 else:
154 raise ValueError("unknown file extension")