xref: /haiku/src/kits/interface/Polygon.cpp (revision 40ceba30d6b162a3a59501900e73f236ccac92ab)
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 #include <string.h>
29 
30 // System Includes -------------------------------------------------------------
31 #include <Polygon.h>
32 
33 // Project Includes ------------------------------------------------------------
34 
35 // Local Includes --------------------------------------------------------------
36 
37 // Local Defines ---------------------------------------------------------------
38 
39 // Globals ---------------------------------------------------------------------
40 
41 //------------------------------------------------------------------------------
42 BPolygon::BPolygon(const BPoint *ptArray, int32 numPoints) :
43 	fBounds(0.0, 0.0, 0.0, 0.0), fCount(numPoints), fPts(NULL)
44 {
45 	if (fCount > 0) {
46 		fPts = new BPoint[numPoints];
47 
48 		// Note the use of memcpy here.  The assumption is that an array of BPoints can
49 		// be copied bit by bit and not use a copy constructor or an assignment
50 		// operator.  This breaks the containment of BPoint but will result in better
51 		// performance.  An example where the memcpy will fail would be if BPoint begins
52 		// to do lazy copying through reference counting.  By copying the bits, we will
53 		// copy reference counting state which will not be relevant at the destination.
54 		// Luckily, BPoint is a very simple class which isn't likely to change much.
55 		// However, it is a risk of this implementation.
56 		//
57 		// If necessary, this code can be changed to iterate over the input array of
58 		// BPoints and use the assignment operator to copy from the source to the
59 		// destination array, one element at a time.
60 		//
61 		// Similar use of memcpy appears later in this implementation also.
62 		//
63 		memcpy(fPts, ptArray, numPoints * sizeof(BPoint));
64 		compute_bounds();
65 	}
66 }
67 //------------------------------------------------------------------------------
68 BPolygon::BPolygon(const BPolygon *poly)
69 {
70 	*this = *poly;
71 }
72 //------------------------------------------------------------------------------
73 BPolygon::BPolygon ()
74 	:	fBounds(0.0, 0.0, 0.0, 0.0),
75 	    fCount(0),
76 		fPts(NULL)
77 {
78 }
79 //------------------------------------------------------------------------------
80 BPolygon::~BPolygon ()
81 {
82 	if (fPts)
83 		delete[] fPts;
84 }
85 //------------------------------------------------------------------------------
86 BPolygon &BPolygon::operator=(const BPolygon &from)
87 {
88 	// Make sure we aren't trying to perform a "self assignment".
89 	if (this != &from) {
90 		fBounds = from.fBounds;
91 		fCount = from.fCount;
92 		if (fCount > 0) {
93 			fPts = new BPoint[fCount];
94 			memcpy(fPts, from.fPts, fCount * sizeof(BPoint));
95 		}
96 	}
97 	return *this;
98 }
99 //------------------------------------------------------------------------------
100 BRect BPolygon::Frame() const
101 {
102 	return fBounds;
103 }
104 //------------------------------------------------------------------------------
105 void BPolygon::AddPoints(const BPoint *ptArray, int32 numPoints)
106 {
107 	if (numPoints > 0) {
108 		BPoint *newPts = new BPoint[fCount + numPoints];
109 		if (fPts) {
110 			memcpy(newPts, fPts, fCount * sizeof(BPoint));
111 			delete fPts;
112 		}
113 		memcpy(newPts + fCount, ptArray, numPoints * sizeof(BPoint));
114 		fPts = newPts;
115 		fCount += numPoints;
116 		compute_bounds();
117 	}
118 }
119 //------------------------------------------------------------------------------
120 int32 BPolygon::CountPoints() const
121 {
122 	return fCount;
123 }
124 //------------------------------------------------------------------------------
125 void BPolygon::MapTo(BRect srcRect, BRect dstRect)
126 {
127 	for (int32 i = 0; i < fCount; i++)
128 		map_pt(fPts + i, srcRect, dstRect);
129 	map_rect(&fBounds, srcRect, dstRect);
130 }
131 //------------------------------------------------------------------------------
132 void BPolygon::PrintToStream () const
133 {
134 	for (int32 i = 0; i < fCount; i++)
135 		fPts[i].PrintToStream();
136 }
137 //------------------------------------------------------------------------------
138 void BPolygon::compute_bounds()
139 {
140 	if (fCount == 0) {
141 		fBounds = BRect(0.0, 0.0, 0.0, 0.0);
142 		return;
143 	}
144 
145 	fBounds = BRect(fPts[0], fPts[0]);
146 
147 	for (int32 i = 1; i < fCount; i++)
148 	{
149 		if (fPts[i].x < fBounds.left)
150 			fBounds.left = fPts[i].x;
151 		if (fPts[i].y < fBounds.top)
152 			fBounds.top = fPts[i].y;
153 		if (fPts[i].x > fBounds.right)
154 			fBounds.right = fPts[i].x;
155 		if (fPts[i].y > fBounds.bottom)
156 			fBounds.bottom = fPts[i].y;
157 	}
158 }
159 //------------------------------------------------------------------------------
160 void BPolygon::map_pt(BPoint *point, BRect srcRect, BRect dstRect)
161 {
162 	point->x = (point->x - srcRect.left) * dstRect.Width() / srcRect.Width()
163 		+ dstRect.left;
164 	point->y = (point->y - srcRect.top) * dstRect.Height() / srcRect.Height()
165 		+ dstRect.top;
166 }
167 //------------------------------------------------------------------------------
168 void BPolygon::map_rect(BRect *rect, BRect srcRect, BRect dstRect)
169 {
170 	BPoint leftTop = rect->LeftTop();
171 	BPoint bottomRight = rect->RightBottom();
172 
173 	map_pt(&leftTop, srcRect, dstRect);
174 	map_pt(&bottomRight, srcRect, dstRect);
175 
176 	*rect = BRect(leftTop, bottomRight);
177 }
178 //------------------------------------------------------------------------------
179 
180 /*
181  * $Log $
182  *
183  * $Id  $
184  *
185  */
186 
187