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