2 * Copyright 2001-2009, Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT license.
6 * Stephan Aßmus, superstippi@gmx.de
7 * Marc Flerackers, mflerackers@androme.be
18 #include <AffineTransform.h>
21 // Limit to avoid integer overflow when calculating the size to allocate
22 #define MAX_POINT_COUNT 10000000
25 BPolygon::BPolygon(const BPoint
* points
, int32 count
)
27 fBounds(0.0f
, 0.0f
, -1.0f
, -1.0f
),
31 _AddPoints(points
, count
, true);
35 BPolygon::BPolygon(const BPolygon
& other
)
37 fBounds(0.0f
, 0.0f
, -1.0f
, -1.0f
),
45 BPolygon::BPolygon(const BPolygon
* other
)
47 fBounds(0.0f
, 0.0f
, -1.0f
, -1.0f
),
57 fBounds(0.0f
, 0.0f
, -1.0f
, -1.0f
),
71 BPolygon::operator=(const BPolygon
& other
)
73 // Make sure we aren't trying to perform a "self assignment".
80 fBounds
.Set(0.0f
, 0.0f
, -1.0f
, -1.0f
);
82 if (_AddPoints(other
.fPoints
, other
.fCount
, false))
83 fBounds
= other
.fBounds
;
90 BPolygon::Frame() const
97 BPolygon::AddPoints(const BPoint
* points
, int32 count
)
99 _AddPoints(points
, count
, true);
104 BPolygon::CountPoints() const
111 BPolygon::MapTo(BRect source
, BRect destination
)
113 for (uint32 i
= 0; i
< fCount
; i
++)
114 _MapPoint(fPoints
+ i
, source
, destination
);
116 _MapRectangle(&fBounds
, source
, destination
);
121 BPolygon::PrintToStream() const
123 for (uint32 i
= 0; i
< fCount
; i
++)
124 fPoints
[i
].PrintToStream();
129 //BPolygon::TransformBy(const BAffineTransform& transform)
131 // transform.Apply(fPoints, (int32)fCount);
137 //BPolygon::TransformBySelf(const BAffineTransform& transform)
139 // TransformBy(transform);
145 //BPolygon::TransformByCopy(const BAffineTransform& transform) const
147 // BPolygon copy(this);
148 // copy.TransformBy(transform);
153 // #pragma mark - BPolygon private methods
157 BPolygon::_AddPoints(const BPoint
* points
, int32 count
, bool computeBounds
)
159 if (points
== NULL
|| count
<= 0)
161 if (count
> MAX_POINT_COUNT
|| (fCount
+ count
) > MAX_POINT_COUNT
) {
162 fprintf(stderr
, "BPolygon::_AddPoints(%" B_PRId32
") - too many points"
167 BPoint
* newPoints
= (BPoint
*)realloc(fPoints
, (fCount
+ count
)
169 if (newPoints
== NULL
) {
170 fprintf(stderr
, "BPolygon::_AddPoints(%" B_PRId32
") out of memory\n",
176 memcpy(fPoints
+ fCount
, points
, count
* sizeof(BPoint
));
187 BPolygon::_ComputeBounds()
190 fBounds
= BRect(0.0, 0.0, -1.0f
, -1.0f
);
194 fBounds
= BRect(fPoints
[0], fPoints
[0]);
196 for (uint32 i
= 1; i
< fCount
; i
++) {
197 if (fPoints
[i
].x
< fBounds
.left
)
198 fBounds
.left
= fPoints
[i
].x
;
200 if (fPoints
[i
].y
< fBounds
.top
)
201 fBounds
.top
= fPoints
[i
].y
;
203 if (fPoints
[i
].x
> fBounds
.right
)
204 fBounds
.right
= fPoints
[i
].x
;
206 if (fPoints
[i
].y
> fBounds
.bottom
)
207 fBounds
.bottom
= fPoints
[i
].y
;
213 BPolygon::_MapPoint(BPoint
* point
, const BRect
& source
,
214 const BRect
& destination
)
216 point
->x
= (point
->x
- source
.left
) * destination
.Width() / source
.Width()
218 point
->y
= (point
->y
- source
.top
) * destination
.Height() / source
.Height()
224 BPolygon::_MapRectangle(BRect
* rect
, const BRect
& source
,
225 const BRect
& destination
)
227 BPoint leftTop
= rect
->LeftTop();
228 BPoint bottomRight
= rect
->RightBottom();
230 _MapPoint(&leftTop
, source
, destination
);
231 _MapPoint(&bottomRight
, source
, destination
);
233 *rect
= BRect(leftTop
, bottomRight
);