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
28 # classes representing bounding boxes
33 """class for bounding boxes
35 This variant requires points in the constructor, and is used for internal
38 def __init__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
):
44 def __add__(self
, other
):
46 return bbox_pt(min(self
.llx_pt
, other
.llx_pt
), min(self
.lly_pt
, other
.lly_pt
),
47 max(self
.urx_pt
, other
.urx_pt
), max(self
.ury_pt
, other
.ury_pt
))
49 def __iadd__(self
, other
):
50 """join two bboxes inplace"""
51 self
.llx_pt
= min(self
.llx_pt
, other
.llx_pt
)
52 self
.lly_pt
= min(self
.lly_pt
, other
.lly_pt
)
53 self
.urx_pt
= max(self
.urx_pt
, other
.urx_pt
)
54 self
.ury_pt
= max(self
.ury_pt
, other
.ury_pt
)
57 def __mul__(self
, other
):
58 """return intersection of two bboxes"""
59 return bbox_pt(max(self
.llx_pt
, other
.llx_pt
), max(self
.lly_pt
, other
.lly_pt
),
60 min(self
.urx_pt
, other
.urx_pt
), min(self
.ury_pt
, other
.ury_pt
))
62 def __imul__(self
, other
):
63 """intersect two bboxes in place"""
64 self
.llx_pt
= max(self
.llx_pt
, other
.llx_pt
)
65 self
.lly_pt
= max(self
.lly_pt
, other
.lly_pt
)
66 self
.urx_pt
= min(self
.urx_pt
, other
.urx_pt
)
67 self
.ury_pt
= min(self
.ury_pt
, other
.ury_pt
)
71 return "%s %s %s %s" % (self
.llx_pt
, self
.lly_pt
, self
.urx_pt
, self
.ury_pt
)
73 def outputPS(self
, file):
74 file.write("%%%%BoundingBox: %d %d %d %d\n" %
75 (math
.floor(self
.llx_pt
), math
.floor(self
.lly_pt
),
76 math
.ceil(self
.urx_pt
), math
.ceil(self
.ury_pt
)))
77 file.write("%%%%HiResBoundingBox: %g %g %g %g\n" %
78 (self
.llx_pt
, self
.lly_pt
, self
.urx_pt
, self
.ury_pt
))
80 def outputPDF(self
, file):
81 file.write("[%d %d %d %d]\n" %
82 (math
.floor(self
.llx_pt
), math
.floor(self
.lly_pt
),
83 math
.ceil(self
.urx_pt
), math
.ceil(self
.ury_pt
)))
85 def intersects(self
, other
):
86 """check, if two bboxes intersect eachother"""
87 return not (self
.llx_pt
> other
.urx_pt
or
88 self
.lly_pt
> other
.ury_pt
or
89 self
.urx_pt
< other
.llx_pt
or
90 self
.ury_pt
< other
.lly_pt
)
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_pt
, lly_pt
= trafo
._apply
(self
.llx_pt
, self
.lly_pt
)
96 lrx
, lry
= trafo
._apply
(self
.urx_pt
, self
.lly_pt
)
97 urx_pt
, ury_pt
= trafo
._apply
(self
.urx_pt
, self
.ury_pt
)
98 ulx
, uly
= trafo
._apply
(self
.llx_pt
, self
.ury_pt
)
100 # Now, by sorting, we obtain the lower left and upper right corner
101 # of the new bounding box.
102 self
.llx_pt
= min(llx_pt
, lrx
, urx_pt
, ulx
)
103 self
.lly_pt
= min(lly_pt
, lry
, ury_pt
, uly
)
104 self
.urx_pt
= max(llx_pt
, lrx
, urx_pt
, ulx
)
105 self
.ury_pt
= max(lly_pt
, lry
, ury_pt
, 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_pt
, lly_pt
= trafo
._apply
(self
.llx_pt
, self
.lly_pt
)
111 lrx
, lry
= trafo
._apply
(self
.urx_pt
, self
.lly_pt
)
112 urx_pt
, ury_pt
= trafo
._apply
(self
.urx_pt
, self
.ury_pt
)
113 ulx
, uly
= trafo
._apply
(self
.llx_pt
, self
.ury_pt
)
115 # Now, by sorting, we obtain the lower left and upper right corner
116 # of the new bounding box.
117 return bbox_pt(min(llx_pt
, lrx
, urx_pt
, ulx
), min(lly_pt
, lry
, ury_pt
, uly
),
118 max(llx_pt
, lrx
, urx_pt
, ulx
), max(lly_pt
, lry
, ury_pt
, uly
))
120 def enlarge(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_pt
= left_pt
= top_pt
= right_pt
= unit
.topt(all
)
127 if bottom
is not None:
128 bottom_pt
= unit
.topt(bottom
)
130 left_pt
= unit
.topt(left
)
132 top_pt
= unit
.topt(top
)
133 if right
is not None:
134 right_pt
= unit
.topt(right
)
135 self
.llx_pt
-= left_pt
136 self
.lly_pt
-= bottom_pt
137 self
.urx_pt
+= right_pt
138 self
.ury_pt
+= top_pt
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_pt
= left_pt
= top_pt
= right_pt
= unit
.topt(all
)
147 if bottom
is not None:
148 bottom_pt
= unit
.topt(bottom
)
150 left_pt
= unit
.topt(left
)
152 top_pt
= unit
.topt(top
)
153 if right
is not None:
154 right_pt
= unit
.topt(right
)
155 return bbox_pt(self
.llx_pt
-left_pt
, self
.lly_pt
-bottom_pt
, self
.urx_pt
+right_pt
, self
.ury_pt
+top_pt
)
158 """return rectangle corresponding to bbox"""
160 return path
.rect_pt(self
.llx_pt
, self
.lly_pt
, self
.urx_pt
-self
.llx_pt
, self
.ury_pt
-self
.lly_pt
)
165 """return height of bbox"""
166 return (self
.ury_pt
-self
.lly_pt
) * unit
.t_pt
169 """return width of bbox"""
170 return (self
.urx_pt
-self
.llx_pt
) * unit
.t_pt
173 """return top coordinate of bbox"""
174 return self
.ury_pt
* unit
.t_pt
177 """return bottom coordinate of bbox"""
178 return self
.lly_pt
* unit
.t_pt
181 """return left coordinate of bbox"""
182 return self
.llx_pt
* unit
.t_pt
185 """return right coordinate of bbox"""
186 return self
.urx_pt
* unit
.t_pt
189 """return coordinates of the center of the bbox"""
190 return 0.5 * (self
.llx_pt
+self
.urx_pt
) * unit
.t_pt
, 0.5 * (self
.lly_pt
+self
.ury_pt
) * unit
.t_pt
195 """class for bounding boxes"""
197 def __init__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
):
198 llx_pt
= unit
.topt(llx_pt
)
199 lly_pt
= unit
.topt(lly_pt
)
200 urx_pt
= unit
.topt(urx_pt
)
201 ury_pt
= unit
.topt(ury_pt
)
202 bbox_pt
.__init
__(self
, llx_pt
, lly_pt
, urx_pt
, ury_pt
)