mirror of
https://github.com/The-Powder-Toy/The-Powder-Toy.git
synced 2025-09-01 20:12:50 +02:00
Allow resizing of custom brushes
This commit is contained in:
@@ -14,9 +14,13 @@
|
|||||||
|
|
||||||
class BitmapBrush: public Brush
|
class BitmapBrush: public Brush
|
||||||
{
|
{
|
||||||
|
protected:
|
||||||
|
ui::Point origSize;
|
||||||
|
unsigned char * origBitmap;
|
||||||
public:
|
public:
|
||||||
BitmapBrush(std::vector<unsigned char> newBitmap, ui::Point rectSize_):
|
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_;
|
ui::Point newSize = rectSize_;
|
||||||
|
|
||||||
@@ -28,28 +32,64 @@ public:
|
|||||||
|
|
||||||
radius = (newSize-ui::Point(1, 1))/2;
|
radius = (newSize-ui::Point(1, 1))/2;
|
||||||
size = newSize;
|
size = newSize;
|
||||||
|
origSize = size;
|
||||||
|
|
||||||
if(bitmap)
|
origBitmap = new unsigned char[size.X*size.Y];
|
||||||
delete[] bitmap;
|
std::fill(origBitmap, origBitmap+(size.X*size.Y), 0);
|
||||||
bitmap = new unsigned char[size.X*size.Y];
|
|
||||||
std::fill(bitmap, bitmap+(size.X*size.Y), 0);
|
|
||||||
for(int y = 0; y < rectSize_.Y; y++)
|
for(int y = 0; y < rectSize_.Y; y++)
|
||||||
{
|
{
|
||||||
for(int x = 0; x < rectSize_.X; x++)
|
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()
|
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<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 ~BitmapBrush()
|
||||||
|
{
|
||||||
|
if(origBitmap)
|
||||||
|
delete[] origBitmap;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user