Port brushes to PlaneAdapter

This commit is contained in:
Tamás Bálint Misius 2024-09-19 19:45:34 +02:00
parent 3b3162063f
commit 7c578b7f13
No known key found for this signature in database
GPG Key ID: 5B472A12F6ECA9F2
7 changed files with 42 additions and 61 deletions

View File

@ -14,25 +14,25 @@ BitmapBrush::BitmapBrush(ui::Point inputSize, unsigned char const *inputBitmap)
newSize.Y += 1;
origSize = newSize;
origBitmap = std::make_unique<unsigned char []>(newSize.X * newSize.Y);
std::fill(&origBitmap[0], &origBitmap[newSize.X * newSize.Y], 0);
origBitmap = PlaneAdapter<std::vector<unsigned char>>(newSize, 0);
for (int y = 0; y < inputSize.Y; y++)
for (int x = 0; x < inputSize.X; x++)
origBitmap[x + y * newSize.X] = inputBitmap[x + y * inputSize.X];
origBitmap[{ x, y }] = inputBitmap[x + y * inputSize.X];
}
BitmapBrush::BitmapBrush(const BitmapBrush &other) : BitmapBrush(other.origSize, &other.origBitmap[0])
BitmapBrush::BitmapBrush(const BitmapBrush &other) : BitmapBrush(other.origSize, other.origBitmap.data())
{
}
std::unique_ptr<unsigned char []> BitmapBrush::GenerateBitmap() const
PlaneAdapter<std::vector<unsigned char>> BitmapBrush::GenerateBitmap() const
{
ui::Point size = radius * 2 + Vec2{ 1, 1 };
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
PlaneAdapter<std::vector<unsigned char>> bitmap;
if (size == origSize)
std::copy(&origBitmap[0], &origBitmap[origSize.X * origSize.Y], &bitmap[0]);
bitmap = origBitmap;
else
{
bitmap = PlaneAdapter<std::vector<unsigned char>>(size);
//Bilinear interpolation
float factorX = ((float)origSize.X)/((float)size.X);
float factorY = ((float)origSize.Y)/((float)size.Y);
@ -48,14 +48,14 @@ std::unique_ptr<unsigned char []> BitmapBrush::GenerateBitmap() const
auto lowerY = int(std::floor(originalY));
auto upperY = int(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];
unsigned char topRight = origBitmap[{ upperX, lowerY }];
unsigned char topLeft = origBitmap[{ lowerX, lowerY }];
unsigned char bottomRight = origBitmap[{ upperX, upperY }];
unsigned char bottomLeft = origBitmap[{ lowerX, upperY }];
float top = LinearInterpolate<float>(topLeft, topRight, float(lowerX), float(upperX), originalX);
float bottom = LinearInterpolate<float>(bottomLeft, bottomRight, float(lowerX), float(upperX), originalX);
float mid = LinearInterpolate<float>(top, bottom, float(lowerY), float(upperY), originalY);
bitmap[(y*size.X)+x] = mid > 128 ? 255 : 0;
bitmap[{ x, y }] = mid > 128 ? 255 : 0;
}
}
}

View File

@ -1,18 +1,17 @@
#pragma once
#include <vector>
#include "Brush.h"
class BitmapBrush: public Brush
{
ui::Point origSize{ 0, 0 };
// 2D array with coords [0, origSize.X) by [0, origSize.Y)
std::unique_ptr<unsigned char []> origBitmap;
PlaneAdapter<std::vector<unsigned char>> origBitmap;
public:
BitmapBrush(ui::Point size, unsigned char const *bitmap);
BitmapBrush(const BitmapBrush &other);
virtual ~BitmapBrush() override = default;
std::unique_ptr<unsigned char []> GenerateBitmap() const override;
PlaneAdapter<std::vector<unsigned char>> GenerateBitmap() const override;
std::unique_ptr<Brush> Clone() const override;
};

View File

@ -1,22 +1,6 @@
#include "Brush.h"
#include "graphics/Graphics.h"
Brush::Brush(const Brush &other)
{
radius = other.radius;
auto size = GetSize();
if (other.bitmap)
{
bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
std::copy(&other.bitmap[0], &other.bitmap[0] + size.X * size.Y, &bitmap[0]);
}
if (other.outline)
{
outline = std::make_unique<unsigned char []>(size.X * size.Y);
std::copy(&other.outline[0], &other.outline[0] + size.X * size.Y, &outline[0]);
}
}
void Brush::InitBitmap()
{
bitmap = GenerateBitmap();
@ -26,26 +10,26 @@ void Brush::InitOutline()
{
InitBitmap();
ui::Point bounds = GetSize();
outline = std::make_unique<unsigned char []>(bounds.X * bounds.Y);
outline = PlaneAdapter<std::vector<unsigned char>>(bounds);
for (int j = 0; j < bounds.Y; j++)
{
for (int i = 0; i < bounds.X; i++)
{
bool value = false;
if (bitmap[i + j * bounds.X])
if (bitmap[{ i, j }])
{
if (i == 0 || j == 0 || i == bounds.X - 1 || j == bounds.Y - 1)
value = true;
else if (!bitmap[(i + 1) + j * bounds.X])
else if (!bitmap[{ i + 1, j }])
value = true;
else if (!bitmap[(i - 1) + j * bounds.X])
else if (!bitmap[{ i - 1, j }])
value = true;
else if (!bitmap[i + (j + 1) * bounds.X])
else if (!bitmap[{ i, j + 1 }])
value = true;
else if (!bitmap[i + (j - 1) * bounds.X])
else if (!bitmap[{ i, j - 1 }])
value = true;
}
outline[i + j * bounds.X] = value ? 0xFF : 0;
outline[{ i, j }] = value ? 0xFF : 0;
}
}
}
@ -122,7 +106,7 @@ void Brush::RenderLine(Graphics *g, ui::Point position1, ui::Point position2) co
void Brush::RenderPoint(Graphics *g, ui::Point position) const
{
g->XorImage(&outline[0], RectBetween(position - radius, position + radius));
g->XorImage(outline.data(), RectBetween(position - radius, position + radius));
}
void Brush::RenderFill(Graphics *g, ui::Point position) const

View File

@ -1,5 +1,6 @@
#pragma once
#include "gui/interface/Point.h"
#include "common/Plane.h"
#include <memory>
class Graphics;
@ -7,8 +8,8 @@ class Brush
{
private:
// 2D arrays indexed by coordinates from [-radius.X, radius.X] by [-radius.Y, radius.Y]
std::unique_ptr<unsigned char []> bitmap;
std::unique_ptr<unsigned char []> outline;
PlaneAdapter<std::vector<unsigned char>> bitmap;
PlaneAdapter<std::vector<unsigned char>> outline;
void InitBitmap();
void InitOutline();
@ -28,7 +29,7 @@ private:
--y;
x = -radius.X;
}
} while (y >= -radius.Y && !parent.bitmap[x + radius.X + (y + radius.Y) * (2 * radius.X + 1)]);
} while (y >= -radius.Y && !parent.bitmap[radius + Vec2<int>{ x, y }]);
return *this;
}
@ -52,11 +53,9 @@ private:
protected:
ui::Point radius{ 0, 0 };
virtual std::unique_ptr<unsigned char []> GenerateBitmap() const = 0;
virtual PlaneAdapter<std::vector<unsigned char>> GenerateBitmap() const = 0;
public:
Brush() = default;
Brush(const Brush &other);
virtual ~Brush() = default;
virtual void AdjustSize(int delta, bool logarithmic, bool keepX, bool keepY);
virtual std::unique_ptr<Brush> Clone() const = 0;

View File

@ -13,10 +13,10 @@ public:
}
virtual ~EllipseBrush() override = default;
std::unique_ptr<unsigned char []> GenerateBitmap() const override
PlaneAdapter<std::vector<unsigned char>> GenerateBitmap() const override
{
ui::Point size = radius * 2 + Vec2{ 1, 1 };
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
PlaneAdapter<std::vector<unsigned char>> bitmap(size);
int rx = radius.X;
int ry = radius.Y;
@ -25,7 +25,7 @@ public:
{
for (int j = 0; j <= 2*ry; j++)
{
bitmap[j*(size.X)+rx] = 255;
bitmap[{ rx, j }] = 255;
}
}
else
@ -48,18 +48,18 @@ public:
{
if (j > yBottom && j < yTop)
{
bitmap[j*(size.X)+i] = 255;
bitmap[j*(size.X)+2*rx-i] = 255;
bitmap[{ i, j }] = 255;
bitmap[{ 2*rx-i, j }] = 255;
}
else
{
bitmap[j*(size.X)+i] = 0;
bitmap[j*(size.X)+2*rx-i] = 0;
bitmap[{ i, j }] = 0;
bitmap[{ 2*rx-i, j }] = 0;
}
}
}
bitmap[size.X/2] = 255;
bitmap[size.X*size.Y-size.X/2-1] = 255;
bitmap[{ size.X/2, 0 }] = 255;
bitmap[{ size.X/2, size.Y-1 }] = 255;
}
return bitmap;
}

View File

@ -6,11 +6,10 @@ class RectangleBrush: public Brush
public:
virtual ~RectangleBrush() override = default;
std::unique_ptr<unsigned char []> GenerateBitmap() const override
PlaneAdapter<std::vector<unsigned char>> GenerateBitmap() const override
{
auto size = GetSize();
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
std::fill(&bitmap[0], &bitmap[0] + size.X * size.Y, 0xFF);
PlaneAdapter<std::vector<unsigned char>> bitmap(size, 0xFF);
return bitmap;
}

View File

@ -7,10 +7,10 @@ class TriangleBrush: public Brush
public:
virtual ~TriangleBrush() override = default;
std::unique_ptr<unsigned char []> GenerateBitmap() const override
PlaneAdapter<std::vector<unsigned char>> GenerateBitmap() const override
{
ui::Point size = radius * 2 + Vec2{ 1, 1 };
auto bitmap = std::make_unique<unsigned char []>(size.X * size.Y);
PlaneAdapter<std::vector<unsigned char>> bitmap(size);
int rx = radius.X;
int ry = radius.Y;
@ -20,11 +20,11 @@ public:
{
if ((abs((rx+2*x)*ry+rx*y) + abs(2*rx*(y-ry)) + abs((rx-2*x)*ry+rx*y))<=(4*rx*ry))
{
bitmap[(y+ry)*(size.X)+x+rx] = 255;
bitmap[{ x+rx, y+ry }] = 255;
}
else
{
bitmap[(y+ry)*(size.X)+x+rx] = 0;
bitmap[{ x+rx, y+ry }] = 0;
}
}
}