xref: /haiku/src/kits/interface/Polygon.cpp (revision 7120e97489acbf17d86d3f33e3b2e68974fd4b23)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		Polygon.h
23 //	Author:			Marc Flerackers (mflerackers@androme.be)
24 //	Description:	BPolygon represents a n-sided area.
25 //------------------------------------------------------------------------------
26 
27 // Standard Includes -----------------------------------------------------------
28 
29 // System Includes -------------------------------------------------------------
30 #include <Polygon.h>
31 
32 // Project Includes ------------------------------------------------------------
33 
34 // Local Includes --------------------------------------------------------------
35 
36 // Local Defines ---------------------------------------------------------------
37 
38 // Globals ---------------------------------------------------------------------
39 
40 //------------------------------------------------------------------------------
41 BPolygon::BPolygon(const BPoint *ptArray, int32 numPoints) :
42 	fBounds(0.0, 0.0, 0.0, 0.0), fCount(numPoints), fPts(NULL)
43 {
44 	if (fCount > 0) {
45 		fPts = new BPoint[numPoints];
46 
47 		// Note the use of memcpy here.  The assumption is that an array of BPoints can
48 		// be copied bit by bit and not use a copy constructor or an assignment
49 		// operator.  This breaks the containment of BPoint but will result in better
50 		// performance.  An example where the memcpy will fail would be if BPoint begins
51 		// to do lazy copying through reference counting.  By copying the bits, we will
52 		// copy reference counting state which will not be relevant at the destination.
53 		// Luckily, BPoint is a very simple class which isn't likely to change much.
54 		// However, it is a risk of this implementation.
55 		//
56 		// If necessary, this code can be changed to iterate over the input array of
57 		// BPoints and use the assignment operator to copy from the source to the
58 		// destination array, one element at a time.
59 		//
60 		// Similar use of memcpy appears later in this implementation also.
61 		//
62 		memcpy(fPts, ptArray, numPoints * sizeof(BPoint));
63 		compute_bounds();
64 	}
65 }
66 //------------------------------------------------------------------------------
67 BPolygon::BPolygon(const BPolygon *poly)
68 {
69 	*this = *poly;
70 }
71 //------------------------------------------------------------------------------
72 BPolygon::BPolygon ()
73 	:	fBounds(0.0, 0.0, 0.0, 0.0),
74 	    fCount(0),
75 		fPts(NULL)
76 {
77 }
78 //------------------------------------------------------------------------------
79 BPolygon::~BPolygon ()
80 {
81 	if (fPts)
82 		delete[] fPts;
83 }
84 //------------------------------------------------------------------------------
85 BPolygon &BPolygon::operator=(const BPolygon &from)
86 {
87 	// Make sure we aren't trying to perform a "self assignment".
88 	if (this != &from) {
89 		fBounds = from.fBounds;
90 		fCount = from.fCount;
91 		if (fCount > 0) {
92 			fPts = new BPoint[fCount];
93 			memcpy(fPts, from.fPts, fCount * sizeof(BPoint));
94 		}
95 	}
96 	return *this;
97 }
98 //------------------------------------------------------------------------------
99 BRect BPolygon::Frame() const
100 {
101 	return fBounds;
102 }
103 //------------------------------------------------------------------------------
104 void BPolygon::AddPoints(const BPoint *ptArray, int32 numPoints)
105 {
106 	if (numPoints > 0) {
107 		BPoint *newPts = new BPoint[fCount + numPoints];
108 		if (fPts) {
109 			memcpy(newPts, fPts, fCount * sizeof(BPoint));
110 			delete fPts;
111 		}
112 		memcpy(newPts + fCount, ptArray, numPoints * sizeof(BPoint));
113 		fPts = newPts;
114 		fCount += numPoints;
115 		compute_bounds();
116 	}
117 }
118 //------------------------------------------------------------------------------
119 int32 BPolygon::CountPoints() const
120 {
121 	return fCount;
122 }
123 //------------------------------------------------------------------------------
124 void BPolygon::MapTo(BRect srcRect, BRect dstRect)
125 {
126 	for (int32 i = 0; i < fCount; i++)
127 		map_pt(fPts + i, srcRect, dstRect);
128 	map_rect(&fBounds, srcRect, dstRect);
129 }
130 //------------------------------------------------------------------------------
131 void BPolygon::PrintToStream () const
132 {
133 	for (int32 i = 0; i < fCount; i++)
134 		fPts[i].PrintToStream();
135 }
136 //------------------------------------------------------------------------------
137 void BPolygon::compute_bounds()
138 {
139 	if (fCount == 0) {
140 		fBounds = BRect(0.0, 0.0, 0.0, 0.0);
141 		return;
142 	}
143 
144 	fBounds = BRect(fPts[0], fPts[0]);
145 
146 	for (int32 i = 1; i < fCount; i++)
147 	{
148 		if (fPts[i].x < fBounds.left)
149 			fBounds.left = fPts[i].x;
150 		if (fPts[i].y < fBounds.top)
151 			fBounds.top = fPts[i].y;
152 		if (fPts[i].x > fBounds.right)
153 			fBounds.right = fPts[i].x;
154 		if (fPts[i].y > fBounds.bottom)
155 			fBounds.bottom = fPts[i].y;
156 	}
157 }
158 //------------------------------------------------------------------------------
159 void BPolygon::map_pt(BPoint *point, BRect srcRect, BRect dstRect)
160 {
161 	point->x = (point->x - srcRect.left) * dstRect.Width() / srcRect.Width()
162 		+ dstRect.left;
163 	point->y = (point->y - srcRect.top) * dstRect.Height() / srcRect.Height()
164 		+ dstRect.top;
165 }
166 //------------------------------------------------------------------------------
167 void BPolygon::map_rect(BRect *rect, BRect srcRect, BRect dstRect)
168 {
169 	BPoint leftTop = rect->LeftTop();
170 	BPoint bottomRight = rect->RightBottom();
171 
172 	map_pt(&leftTop, srcRect, dstRect);
173 	map_pt(&bottomRight, srcRect, dstRect);
174 
175 	*rect = BRect(leftTop, bottomRight);
176 }
177 //------------------------------------------------------------------------------
178 
179 /*
180  * $Log $
181  *
182  * $Id  $
183  *
184  */
185 
186