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
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; newSize.Y += 1;
origSize = newSize; origSize = newSize;
origBitmap = std::make_unique<unsigned char []>(newSize.X * newSize.Y); origBitmap = PlaneAdapter<std::vector<unsigned char>>(newSize, 0);
std::fill(&origBitmap[0], &origBitmap[newSize.X * newSize.Y], 0);
for (int y = 0; y < inputSize.Y; y++) for (int y = 0; y < inputSize.Y; y++)
for (int x = 0; x < inputSize.X; x++) 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 }; 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) if (size == origSize)
std::copy(&origBitmap[0], &origBitmap[origSize.X * origSize.Y], &bitmap[0]); bitmap = origBitmap;
else else
{ {
bitmap = PlaneAdapter<std::vector<unsigned char>>(size);
//Bilinear interpolation //Bilinear interpolation
float factorX = ((float)origSize.X)/((float)size.X); float factorX = ((float)origSize.X)/((float)size.X);
float factorY = ((float)origSize.Y)/((float)size.Y); 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 lowerY = int(std::floor(originalY));
auto upperY = int(std::min((float)(origSize.Y-1), std::floor(originalY+1.0f))); auto upperY = int(std::min((float)(origSize.Y-1), std::floor(originalY+1.0f)));
unsigned char topRight = origBitmap[(lowerY*origSize.X)+upperX]; unsigned char topRight = origBitmap[{ upperX, lowerY }];
unsigned char topLeft = origBitmap[(lowerY*origSize.X)+lowerX]; unsigned char topLeft = origBitmap[{ lowerX, lowerY }];
unsigned char bottomRight = origBitmap[(upperY*origSize.X)+upperX]; unsigned char bottomRight = origBitmap[{ upperX, upperY }];
unsigned char bottomLeft = origBitmap[(upperY*origSize.X)+lowerX]; unsigned char bottomLeft = origBitmap[{ lowerX, upperY }];
float top = LinearInterpolate<float>(topLeft, topRight, float(lowerX), float(upperX), originalX); float top = LinearInterpolate<float>(topLeft, topRight, float(lowerX), float(upperX), originalX);
float bottom = LinearInterpolate<float>(bottomLeft, bottomRight, 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); 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 #pragma once
#include <vector>
#include "Brush.h" #include "Brush.h"
class BitmapBrush: public Brush class BitmapBrush: public Brush
{ {
ui::Point origSize{ 0, 0 }; ui::Point origSize{ 0, 0 };
// 2D array with coords [0, origSize.X) by [0, origSize.Y) // 2D array with coords [0, origSize.X) by [0, origSize.Y)
std::unique_ptr<unsigned char []> origBitmap; PlaneAdapter<std::vector<unsigned char>> origBitmap;
public: public:
BitmapBrush(ui::Point size, unsigned char const *bitmap); BitmapBrush(ui::Point size, unsigned char const *bitmap);
BitmapBrush(const BitmapBrush &other); BitmapBrush(const BitmapBrush &other);
virtual ~BitmapBrush() override = default; 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; std::unique_ptr<Brush> Clone() const override;
}; };

View File

@@ -1,22 +1,6 @@
#include "Brush.h" #include "Brush.h"
#include "graphics/Graphics.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() void Brush::InitBitmap()
{ {
bitmap = GenerateBitmap(); bitmap = GenerateBitmap();
@@ -26,26 +10,26 @@ void Brush::InitOutline()
{ {
InitBitmap(); InitBitmap();
ui::Point bounds = GetSize(); 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 j = 0; j < bounds.Y; j++)
{ {
for (int i = 0; i < bounds.X; i++) for (int i = 0; i < bounds.X; i++)
{ {
bool value = false; 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) if (i == 0 || j == 0 || i == bounds.X - 1 || j == bounds.Y - 1)
value = true; value = true;
else if (!bitmap[(i + 1) + j * bounds.X]) else if (!bitmap[{ i + 1, j }])
value = true; value = true;
else if (!bitmap[(i - 1) + j * bounds.X]) else if (!bitmap[{ i - 1, j }])
value = true; value = true;
else if (!bitmap[i + (j + 1) * bounds.X]) else if (!bitmap[{ i, j + 1 }])
value = true; value = true;
else if (!bitmap[i + (j - 1) * bounds.X]) else if (!bitmap[{ i, j - 1 }])
value = true; 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 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 void Brush::RenderFill(Graphics *g, ui::Point position) const

View File

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

View File

@@ -13,10 +13,10 @@ public:
} }
virtual ~EllipseBrush() override = default; 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 }; 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 rx = radius.X;
int ry = radius.Y; int ry = radius.Y;
@@ -25,7 +25,7 @@ public:
{ {
for (int j = 0; j <= 2*ry; j++) for (int j = 0; j <= 2*ry; j++)
{ {
bitmap[j*(size.X)+rx] = 255; bitmap[{ rx, j }] = 255;
} }
} }
else else
@@ -48,18 +48,18 @@ public:
{ {
if (j > yBottom && j < yTop) if (j > yBottom && j < yTop)
{ {
bitmap[j*(size.X)+i] = 255; bitmap[{ i, j }] = 255;
bitmap[j*(size.X)+2*rx-i] = 255; bitmap[{ 2*rx-i, j }] = 255;
} }
else else
{ {
bitmap[j*(size.X)+i] = 0; bitmap[{ i, j }] = 0;
bitmap[j*(size.X)+2*rx-i] = 0; bitmap[{ 2*rx-i, j }] = 0;
} }
} }
} }
bitmap[size.X/2] = 255; bitmap[{ size.X/2, 0 }] = 255;
bitmap[size.X*size.Y-size.X/2-1] = 255; bitmap[{ size.X/2, size.Y-1 }] = 255;
} }
return bitmap; return bitmap;
} }

View File

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

View File

@@ -7,10 +7,10 @@ class TriangleBrush: public Brush
public: public:
virtual ~TriangleBrush() override = default; 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 }; 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 rx = radius.X;
int ry = radius.Y; 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)) 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 else
{ {
bitmap[(y+ry)*(size.X)+x+rx] = 0; bitmap[{ x+rx, y+ry }] = 0;
} }
} }
} }