From 815c38625d4d164cd1c655c096b7095dac79cd51 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 4 Feb 2007 13:32:36 +0000 Subject: [PATCH] Applied patch by Vasilis Kaoutsis: * replaced new[] with malloc()/realloc() where appropriate - since we're messing with the bits anyway, this makes the code slightly faster. * however, we might want to throw some std::bad_alloc exceptions to deal correctly with low memory situations. * cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20065 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/interface/Polygon.h | 121 ++++-------- src/kits/interface/Polygon.cpp | 350 +++++++++++++++------------------ src/kits/interface/View.cpp | 8 +- 3 files changed, 209 insertions(+), 270 deletions(-) diff --git a/headers/os/interface/Polygon.h b/headers/os/interface/Polygon.h index 32a00553d6..1eddbd31fe 100644 --- a/headers/os/interface/Polygon.h +++ b/headers/os/interface/Polygon.h @@ -1,84 +1,45 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Polygon.h -// Author: Marc Flerackers (mflerackers@androme.be) -// Description: BPolygon represents a n-sided area. -//------------------------------------------------------------------------------ - +/* + * Copyright 2001-2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marc Flerackers, mflerackers@androme.be + */ #ifndef _POLYGON_H -#define _POLYGON_H - -// Standard Includes ----------------------------------------------------------- - -// System Includes ------------------------------------------------------------- -#include -#include -#include - -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- - -// BPolygon class -------------------------------------------------------------- -class BPolygon { +#define _POLYGON_H -public: - BPolygon(const BPoint *ptArray, int32 numPoints); - BPolygon(); - BPolygon(const BPolygon *poly); -virtual ~BPolygon(); - - BPolygon &operator=(const BPolygon &from); - - BRect Frame() const; - void AddPoints(const BPoint *ptArray, int32 numPoints); - int32 CountPoints() const; - void MapTo(BRect srcRect, BRect dstRect); - void PrintToStream() const; - -private: - -friend class BView; - - void compute_bounds(); - void map_pt(BPoint *point, BRect srcRect, BRect dstRect); - void map_rect(BRect *rect, BRect srcRect, BRect dstRect); - - BRect fBounds; - int32 fCount; - BPoint *fPts; + +#include +#include +#include + + +class BPolygon { + public: + BPolygon(const BPoint *ptArray, int32 numPoints); + BPolygon(const BPolygon *polygon); + BPolygon(); + virtual ~BPolygon(); + + BPolygon &operator=(const BPolygon &from); + + BRect Frame() const; + void AddPoints(const BPoint *ptArray, int32 numPoints); + int32 CountPoints() const; + void MapTo(BRect srcRect, BRect dstRect); + void PrintToStream() const; + + private: + friend class BView; + + void _ComputeBounds(); + void _MapPoint(BPoint *point, BRect srcRect, BRect dstRect); + void _MapRectangle(BRect *rect, BRect srcRect, BRect dstRect); + + private: + BRect fBounds; + int32 fCount; + BPoint *fPoints; }; -//------------------------------------------------------------------------------ -#endif // _POLYGON_H_ - -/* - * $Log $ - * - * $Id $ - * - */ - +#endif // _POLYGON_H_ diff --git a/src/kits/interface/Polygon.cpp b/src/kits/interface/Polygon.cpp index 4e278c0156..43b69ec1e7 100644 --- a/src/kits/interface/Polygon.cpp +++ b/src/kits/interface/Polygon.cpp @@ -1,186 +1,164 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Polygon.h -// Author: Marc Flerackers (mflerackers@androme.be) -// Description: BPolygon represents a n-sided area. -//------------------------------------------------------------------------------ - -// Standard Includes ----------------------------------------------------------- -#include - -// System Includes ------------------------------------------------------------- -#include - -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- - -//------------------------------------------------------------------------------ -BPolygon::BPolygon(const BPoint *ptArray, int32 numPoints) : - fBounds(0.0, 0.0, 0.0, 0.0), fCount(numPoints), fPts(NULL) -{ - if (fCount > 0) { - fPts = new BPoint[numPoints]; - - // Note the use of memcpy here. The assumption is that an array of BPoints can - // be copied bit by bit and not use a copy constructor or an assignment - // operator. This breaks the containment of BPoint but will result in better - // performance. An example where the memcpy will fail would be if BPoint begins - // to do lazy copying through reference counting. By copying the bits, we will - // copy reference counting state which will not be relevant at the destination. - // Luckily, BPoint is a very simple class which isn't likely to change much. - // However, it is a risk of this implementation. - // - // If necessary, this code can be changed to iterate over the input array of - // BPoints and use the assignment operator to copy from the source to the - // destination array, one element at a time. - // - // Similar use of memcpy appears later in this implementation also. - // - memcpy(fPts, ptArray, numPoints * sizeof(BPoint)); - compute_bounds(); - } -} -//------------------------------------------------------------------------------ -BPolygon::BPolygon(const BPolygon *poly) -{ - *this = *poly; -} -//------------------------------------------------------------------------------ -BPolygon::BPolygon () - : fBounds(0.0, 0.0, 0.0, 0.0), - fCount(0), - fPts(NULL) -{ -} -//------------------------------------------------------------------------------ -BPolygon::~BPolygon () -{ - if (fPts) - delete[] fPts; -} -//------------------------------------------------------------------------------ -BPolygon &BPolygon::operator=(const BPolygon &from) -{ - // Make sure we aren't trying to perform a "self assignment". - if (this != &from) { - fBounds = from.fBounds; - fCount = from.fCount; - if (fCount > 0) { - fPts = new BPoint[fCount]; - memcpy(fPts, from.fPts, fCount * sizeof(BPoint)); - } - } - return *this; -} -//------------------------------------------------------------------------------ -BRect BPolygon::Frame() const -{ - return fBounds; -} -//------------------------------------------------------------------------------ -void BPolygon::AddPoints(const BPoint *ptArray, int32 numPoints) -{ - if (numPoints > 0) { - BPoint *newPts = new BPoint[fCount + numPoints]; - if (fPts) { - memcpy(newPts, fPts, fCount * sizeof(BPoint)); - delete fPts; - } - memcpy(newPts + fCount, ptArray, numPoints * sizeof(BPoint)); - fPts = newPts; - fCount += numPoints; - compute_bounds(); - } -} -//------------------------------------------------------------------------------ -int32 BPolygon::CountPoints() const -{ - return fCount; -} -//------------------------------------------------------------------------------ -void BPolygon::MapTo(BRect srcRect, BRect dstRect) -{ - for (int32 i = 0; i < fCount; i++) - map_pt(fPts + i, srcRect, dstRect); - map_rect(&fBounds, srcRect, dstRect); -} -//------------------------------------------------------------------------------ -void BPolygon::PrintToStream () const -{ - for (int32 i = 0; i < fCount; i++) - fPts[i].PrintToStream(); -} -//------------------------------------------------------------------------------ -void BPolygon::compute_bounds() -{ - if (fCount == 0) { - fBounds = BRect(0.0, 0.0, 0.0, 0.0); - return; - } - - fBounds = BRect(fPts[0], fPts[0]); - - for (int32 i = 1; i < fCount; i++) - { - if (fPts[i].x < fBounds.left) - fBounds.left = fPts[i].x; - if (fPts[i].y < fBounds.top) - fBounds.top = fPts[i].y; - if (fPts[i].x > fBounds.right) - fBounds.right = fPts[i].x; - if (fPts[i].y > fBounds.bottom) - fBounds.bottom = fPts[i].y; - } -} -//------------------------------------------------------------------------------ -void BPolygon::map_pt(BPoint *point, BRect srcRect, BRect dstRect) -{ - point->x = (point->x - srcRect.left) * dstRect.Width() / srcRect.Width() - + dstRect.left; - point->y = (point->y - srcRect.top) * dstRect.Height() / srcRect.Height() - + dstRect.top; -} -//------------------------------------------------------------------------------ -void BPolygon::map_rect(BRect *rect, BRect srcRect, BRect dstRect) -{ - BPoint leftTop = rect->LeftTop(); - BPoint bottomRight = rect->RightBottom(); - - map_pt(&leftTop, srcRect, dstRect); - map_pt(&bottomRight, srcRect, dstRect); - - *rect = BRect(leftTop, bottomRight); -} -//------------------------------------------------------------------------------ - -/* - * $Log $ - * - * $Id $ - * - */ - +/* + * Copyright 2001-2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Marc Flerackers, mflerackers@androme.be + */ + + +#include + +#include +#include + + +BPolygon::BPolygon(const BPoint *ptArray, int32 numPoints) + : + fBounds(0.0, 0.0, 0.0, 0.0), + fCount(numPoints), + fPoints(NULL) +{ + if (fCount > 0) { + fPoints = (BPoint*)malloc(numPoints * sizeof(BPoint)); + + // Note the use of memcpy here. The assumption is that an array of BPoints can + // be copied bit by bit and not use a copy constructor or an assignment + // operator. This breaks the containment of BPoint but will result in better + // performance. An example where the memcpy will fail would be if BPoint begins + // to do lazy copying through reference counting. By copying the bits, we will + // copy reference counting state which will not be relevant at the destination. + // Luckily, BPoint is a very simple class which isn't likely to change much. + // + // Similar use of memcpy appears later in this implementation also. + + memcpy(fPoints, ptArray, numPoints * sizeof(BPoint)); + _ComputeBounds(); + } +} + + +BPolygon::BPolygon(const BPolygon *poly) +{ + *this = *poly; +} + + +BPolygon::BPolygon() + : + fBounds(0.0, 0.0, 0.0, 0.0), + fCount(0), + fPoints(NULL) +{ +} + + +BPolygon::~BPolygon() +{ + free(fPoints); +} + + +BPolygon & +BPolygon::operator=(const BPolygon &from) +{ + // Make sure we aren't trying to perform a "self assignment". + if (this != &from) { + fBounds = from.fBounds; + fCount = from.fCount; + if (fCount > 0) { + fPoints = (BPoint*)malloc(fCount * sizeof(BPoint)); + memcpy(fPoints, from.fPoints, fCount * sizeof(BPoint)); + } + } + return *this; +} + + +BRect +BPolygon::Frame() const +{ + return fBounds; +} + + +void +BPolygon::AddPoints(const BPoint *ptArray, int32 numPoints) +{ + if (numPoints > 0) { + fPoints = (BPoint*)realloc(fPoints, (fCount + numPoints) * sizeof(BPoint)); + memcpy(fPoints + fCount + numPoints, ptArray, numPoints * sizeof(BPoint)); + fCount += numPoints; + _ComputeBounds(); + } +} + + +int32 +BPolygon::CountPoints() const +{ + return fCount; +} + + +void +BPolygon::MapTo(BRect srcRect, BRect dstRect) +{ + for (int32 i = 0; i < fCount; i++) + _MapPoint(fPoints + i, srcRect, dstRect); + _MapRectangle(&fBounds, srcRect, dstRect); +} + + +void +BPolygon::PrintToStream () const +{ + for (int32 i = 0; i < fCount; i++) + fPoints[i].PrintToStream(); +} + + +void +BPolygon::_ComputeBounds() +{ + if (fCount == 0) { + fBounds = BRect(0.0, 0.0, 0.0, 0.0); + return; + } + + fBounds = BRect(fPoints[0], fPoints[0]); + + for (int32 i = 1; i < fCount; i++) { + if (fPoints[i].x < fBounds.left) + fBounds.left = fPoints[i].x; + if (fPoints[i].y < fBounds.top) + fBounds.top = fPoints[i].y; + if (fPoints[i].x > fBounds.right) + fBounds.right = fPoints[i].x; + if (fPoints[i].y > fBounds.bottom) + fBounds.bottom = fPoints[i].y; + } +} + + +void +BPolygon::_MapPoint(BPoint *point, BRect srcRect, BRect dstRect) +{ + point->x = (point->x - srcRect.left) * dstRect.Width() / srcRect.Width() + + dstRect.left; + point->y = (point->y - srcRect.top) * dstRect.Height() / srcRect.Height() + + dstRect.top; +} + + +void +BPolygon::_MapRectangle(BRect *rect, BRect srcRect, BRect dstRect) +{ + BPoint leftTop = rect->LeftTop(); + BPoint bottomRight = rect->RightBottom(); + + _MapPoint(&leftTop, srcRect, dstRect); + _MapPoint(&bottomRight, srcRect, dstRect); + + *rect = BRect(leftTop, bottomRight); +} diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index ab4c22ce6a..bca0bd83a3 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -2583,7 +2583,7 @@ BView::StrokePolygon(const BPolygon *polygon, bool closed, pattern p) if (!polygon) return; - StrokePolygon(polygon->fPts, polygon->fCount, polygon->Frame(), closed, p); + StrokePolygon(polygon->fPoints, polygon->fCount, polygon->Frame(), closed, p); } @@ -2592,7 +2592,7 @@ BView::StrokePolygon(const BPoint *ptArray, int32 numPoints, bool closed, patter { BPolygon polygon(ptArray, numPoints); - StrokePolygon(polygon.fPts, polygon.fCount, polygon.Frame(), closed, p); + StrokePolygon(polygon.fPoints, polygon.fCount, polygon.Frame(), closed, p); } @@ -2617,7 +2617,7 @@ BView::StrokePolygon(const BPoint *ptArray, int32 numPoints, BRect bounds, fOwner->fLink->Attach(polygon.Frame()); fOwner->fLink->Attach(closed); fOwner->fLink->Attach(polygon.fCount); - fOwner->fLink->Attach(polygon.fPts, polygon.fCount * sizeof(BPoint)); + fOwner->fLink->Attach(polygon.fPoints, polygon.fCount * sizeof(BPoint)); _FlushIfNotInTransaction(); } else { @@ -2642,7 +2642,7 @@ BView::FillPolygon(const BPolygon *polygon, ::pattern pattern) polygon->fCount * sizeof(BPoint) + sizeof(BRect) + sizeof(int32)) == B_OK) { fOwner->fLink->Attach(polygon->Frame()); fOwner->fLink->Attach(polygon->fCount); - fOwner->fLink->Attach(polygon->fPts, polygon->fCount * sizeof(BPoint)); + fOwner->fLink->Attach(polygon->fPoints, polygon->fCount * sizeof(BPoint)); _FlushIfNotInTransaction(); } else {