uppercase python
[PyX/mjg.git] / pyx / bbox.py
blob7a40110c5168874fde25e1b8c9e29d96a2e779bb
1 #!/usr/bin/env python
2 # -*- coding: ISO-8859-1 -*-
5 # Copyright (C) 2002-2004 Jörg Lehmann <joergl@users.sourceforge.net>
6 # Copyright (C) 2002-2004 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 import math
25 import unit
28 # classes representing bounding boxes
31 class _bbox:
33 """class for bounding boxes
35 This variant requires points in the constructor, and is used for internal
36 purposes."""
38 def __init__(self, llx, lly, urx, ury):
39 self.llx = llx
40 self.lly = lly
41 self.urx = urx
42 self.ury = ury
44 def __add__(self, other):
45 """join two bboxes"""
46 return _bbox(min(self.llx, other.llx), min(self.lly, other.lly),
47 max(self.urx, other.urx), max(self.ury, other.ury))
49 def __iadd__(self, other):
50 """join two bboxes inplace"""
51 self.llx = min(self.llx, other.llx)
52 self.lly = min(self.lly, other.lly)
53 self.urx = max(self.urx, other.urx)
54 self.ury = max(self.ury, other.ury)
55 return self
57 def __mul__(self, other):
58 """return intersection of two bboxes"""
59 return _bbox(max(self.llx, other.llx), max(self.lly, other.lly),
60 min(self.urx, other.urx), min(self.ury, other.ury))
62 def __imul__(self, other):
63 """intersect two bboxes in place"""
64 self.llx = max(self.llx, other.llx)
65 self.lly = max(self.lly, other.lly)
66 self.urx = min(self.urx, other.urx)
67 self.ury = min(self.ury, other.ury)
68 return self
70 def __str__(self):
71 return "%s %s %s %s" % (self.llx, self.lly, self.urx, self.ury)
73 def outputPS(self, file):
74 file.write("%%%%BoundingBox: %d %d %d %d\n" %
75 (math.floor(self.llx), math.floor(self.lly),
76 math.ceil(self.urx), math.ceil(self.ury)))
77 file.write("%%%%HiResBoundingBox: %g %g %g %g\n" %
78 (self.llx, self.lly, self.urx, self.ury))
80 def outputPDF(self, file):
81 file.write("/MediaBox [%d %d %d %d]\n" %
82 (math.floor(self.llx), math.floor(self.lly),
83 math.ceil(self.urx), math.ceil(self.ury)))
85 def intersects(self, other):
86 """check, if two bboxes intersect eachother"""
87 return not (self.llx > other.urx or
88 self.lly > other.ury or
89 self.urx < other.llx or
90 self.ury < other.lly)
92 def transform(self, trafo):
93 """transform bbox in place by trafo"""
94 # we have to transform all four corner points of the bbox
95 llx, lly = trafo._apply(self.llx, self.lly)
96 lrx, lry = trafo._apply(self.urx, self.lly)
97 urx, ury = trafo._apply(self.urx, self.ury)
98 ulx, uly = trafo._apply(self.llx, self.ury)
100 # Now, by sorting, we obtain the lower left and upper right corner
101 # of the new bounding box.
102 self.llx = min(llx, lrx, urx, ulx)
103 self.lly = min(lly, lry, ury, uly)
104 self.urx = max(llx, lrx, urx, ulx)
105 self.ury = max(lly, lry, ury, uly)
107 def transformed(self, trafo):
108 """return bbox transformed by trafo"""
109 # we have to transform all four corner points of the bbox
110 llx, lly = trafo._apply(self.llx, self.lly)
111 lrx, lry = trafo._apply(self.urx, self.lly)
112 urx, ury = trafo._apply(self.urx, self.ury)
113 ulx, uly = trafo._apply(self.llx, self.ury)
115 # Now, by sorting, we obtain the lower left and upper right corner
116 # of the new bounding box.
117 return _bbox(min(llx, lrx, urx, ulx), min(lly, lry, ury, uly),
118 max(llx, lrx, urx, ulx), max(lly, lry, ury, uly))
120 def enlarged(self, all=0, bottom=None, left=None, top=None, right=None):
121 """enlarge bbox in place
123 all is used, if bottom, left, top and/or right are not given.
126 _bottom = _left = _top = _right = unit.topt(unit.length(all, default_type="v"))
127 if bottom is not None:
128 _bottom = unit.topt(unit.length(bottom, default_type="v"))
129 if left is not None:
130 _left = unit.topt(unit.length(left, default_type="v"))
131 if top is not None:
132 _top = unit.topt(unit.length(top, default_type="v"))
133 if right is not None:
134 _right = unit.topt(unit.length(right, default_type="v"))
135 self.llx -= _left
136 self.lly -= _bottom
137 self.urx += _right
138 self.ury += top
140 def enlarged(self, all=0, bottom=None, left=None, top=None, right=None):
141 """return bbox enlarged
143 all is used, if bottom, left, top and/or right are not given.
146 _bottom = _left = _top = _right = unit.topt(unit.length(all, default_type="v"))
147 if bottom is not None:
148 _bottom = unit.topt(unit.length(bottom, default_type="v"))
149 if left is not None:
150 _left = unit.topt(unit.length(left, default_type="v"))
151 if top is not None:
152 _top = unit.topt(unit.length(top, default_type="v"))
153 if right is not None:
154 _right = unit.topt(unit.length(right, default_type="v"))
155 return _bbox(self.llx-_left, self.lly-_bottom, self.urx+_right, self.ury+_top)
157 def rect(self):
158 """return rectangle corresponding to bbox"""
159 import path
160 return path.rect_pt(self.llx, self.lly, self.urx-self.llx, self.ury-self.lly)
162 path = rect
164 def height(self):
165 """return height of bbox"""
166 return unit.t_pt(self.ury-self.lly)
168 def width(self):
169 """return width of bbox"""
170 return unit.t_pt(self.urx-self.llx)
172 def top(self):
173 """return top coordinate of bbox"""
174 return unit.t_pt(self.ury)
176 def bottom(self):
177 """return bottom coordinate of bbox"""
178 return unit.t_pt(self.lly)
180 def left(self):
181 """return left coordinate of bbox"""
182 return unit.t_pt(self.llx)
184 def right(self):
185 """return right coordinate of bbox"""
186 return unit.t_pt(self.urx)
189 class bbox(_bbox):
191 """class for bounding boxes"""
193 def __init__(self, llx, lly, urx, ury):
194 llx = unit.topt(llx)
195 lly = unit.topt(lly)
196 urx = unit.topt(urx)
197 ury = unit.topt(ury)
198 _bbox.__init__(self, llx, lly, urx, ury)