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