From da554cfef24b6a207db50507e7dae3513b36e59b Mon Sep 17 00:00:00 2001 From: Simon Robertshaw Date: Sun, 18 Nov 2012 22:25:24 +0000 Subject: [PATCH] Allow resizing of custom brushes --- src/game/BitmapBrush.h | 64 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 52 insertions(+), 12 deletions(-) diff --git a/src/game/BitmapBrush.h b/src/game/BitmapBrush.h index dd8dd92d9..e1c0445a9 100644 --- a/src/game/BitmapBrush.h +++ b/src/game/BitmapBrush.h @@ -14,9 +14,13 @@ class BitmapBrush: public Brush { +protected: + ui::Point origSize; + unsigned char * origBitmap; public: BitmapBrush(std::vector newBitmap, ui::Point rectSize_): - Brush(ui::Point(0, 0)) + Brush(ui::Point(0, 0)), + origSize(0, 0) { ui::Point newSize = rectSize_; @@ -28,28 +32,64 @@ public: radius = (newSize-ui::Point(1, 1))/2; size = newSize; + origSize = size; - if(bitmap) - delete[] bitmap; - bitmap = new unsigned char[size.X*size.Y]; - std::fill(bitmap, bitmap+(size.X*size.Y), 0); + origBitmap = new unsigned char[size.X*size.Y]; + std::fill(origBitmap, origBitmap+(size.X*size.Y), 0); for(int y = 0; y < rectSize_.Y; y++) { for(int x = 0; x < rectSize_.X; x++) { - bitmap[(y*size.X)+x] = newBitmap[(y*rectSize_.X)+x]; + if(newBitmap[(y*rectSize_.X)+x] >= 128) + origBitmap[(y*size.X)+x] = newBitmap[(y*rectSize_.X)+x]; } } - updateOutline(); + SetRadius(radius); }; - virtual void SetRadius(ui::Point radius) - { - //Do nothing... this brush is a fixed size - } virtual void GenerateBitmap() { - //Do nothing + if(origBitmap) + { + if(bitmap) + delete[] bitmap; + bitmap = new unsigned char[size.X*size.Y]; + if(size == origSize) + std::copy(origBitmap, origBitmap+(origSize.X*origSize.Y), bitmap); + else + { + //Bilinear interpolation + float factorX = ((float)origSize.X)/((float)size.X); + float factorY = ((float)origSize.Y)/((float)size.Y); + for(int y = 0; y < size.Y; y++) + { + for(int x = 0; x < size.X; x++) + { + float originalY = ((float)y)*factorY; + float originalX = ((float)x)*factorX; + + int lowerX = std::floor(originalX); + int upperX = std::min((float)(origSize.X-1), std::floor(originalX+1.0f)); + int lowerY = std::floor(originalY); + int upperY = std::min((float)(origSize.Y-1), std::floor(originalY+1.0f)); + + unsigned char topRight = origBitmap[(lowerY*origSize.X)+upperX]; + unsigned char topLeft = origBitmap[(lowerY*origSize.X)+lowerX]; + unsigned char bottomRight = origBitmap[(upperY*origSize.X)+upperX]; + unsigned char bottomLeft = origBitmap[(upperY*origSize.X)+lowerX]; + float top = LinearInterpolate(topLeft, topRight, lowerX, upperX, originalX); + float bottom = LinearInterpolate(bottomLeft, bottomRight, lowerX, upperX, originalX); + float mid = LinearInterpolate(top, bottom, lowerY, upperY, originalY); + bitmap[(y*size.X)+x] = mid > 128 ? 255 : 0; + } + } + } + } + } + virtual ~BitmapBrush() + { + if(origBitmap) + delete[] origBitmap; } };