summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-11-18 22:25:24 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-11-18 22:25:24 (GMT)
commitda554cfef24b6a207db50507e7dae3513b36e59b (patch)
tree059988ada2a098236a5202b4ef0f4837926c7443 /src
parentf3307e47a850091d9ef16da015c31fd2bb71e44b (diff)
downloadpowder-da554cfef24b6a207db50507e7dae3513b36e59b.zip
powder-da554cfef24b6a207db50507e7dae3513b36e59b.tar.gz
Allow resizing of custom brushes
Diffstat (limited to 'src')
-rw-r--r--src/game/BitmapBrush.h62
1 files changed, 51 insertions, 11 deletions
diff --git a/src/game/BitmapBrush.h b/src/game/BitmapBrush.h
index dd8dd92..e1c0445 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<unsigned char> 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)
+ virtual void GenerateBitmap()
{
- //Do nothing... this brush is a fixed size
+ 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<float>(topLeft, topRight, lowerX, upperX, originalX);
+ float bottom = LinearInterpolate<float>(bottomLeft, bottomRight, lowerX, upperX, originalX);
+ float mid = LinearInterpolate<float>(top, bottom, lowerY, upperY, originalY);
+ bitmap[(y*size.X)+x] = mid > 128 ? 255 : 0;
+ }
+ }
+ }
+ }
}
- virtual void GenerateBitmap()
+ virtual ~BitmapBrush()
{
- //Do nothing
+ if(origBitmap)
+ delete[] origBitmap;
}
};