mirror of
https://github.com/amyinspace/MagicSetEditor2.git
synced 2026-06-12 13:37:00 -04:00
Change tabs to two spaces.
This commit is contained in:
+115
-115
@@ -14,164 +14,164 @@
|
||||
|
||||
AlphaMask::AlphaMask() : alpha(nullptr), lefts(nullptr), rights(nullptr) {}
|
||||
AlphaMask::AlphaMask(const Image& img) : alpha(nullptr), lefts(nullptr), rights(nullptr) {
|
||||
load(img);
|
||||
load(img);
|
||||
}
|
||||
AlphaMask::~AlphaMask() {
|
||||
clear();
|
||||
clear();
|
||||
}
|
||||
|
||||
void AlphaMask::clear() {
|
||||
delete[] alpha; alpha = nullptr;
|
||||
delete[] lefts; lefts = nullptr;
|
||||
delete[] rights; rights = nullptr;
|
||||
delete[] alpha; alpha = nullptr;
|
||||
delete[] lefts; lefts = nullptr;
|
||||
delete[] rights; rights = nullptr;
|
||||
}
|
||||
|
||||
void AlphaMask::load(const Image& img) {
|
||||
size_t old_n = alpha ? size.x * size.y : 0;
|
||||
size.x = img.GetWidth();
|
||||
size.y = img.GetHeight();
|
||||
// Memory
|
||||
size_t n = size.x * size.y;
|
||||
if (n != old_n) {
|
||||
delete[] alpha;
|
||||
alpha = new Byte[n];
|
||||
}
|
||||
delete[] lefts; lefts = nullptr;
|
||||
delete[] rights; rights = nullptr;
|
||||
// Copy red chanel to alpha
|
||||
Byte* from = img.GetData(), *to = alpha;
|
||||
for (size_t i = 0 ; i < n ; ++i) {
|
||||
to[i] = from[3*i];
|
||||
}
|
||||
size_t old_n = alpha ? size.x * size.y : 0;
|
||||
size.x = img.GetWidth();
|
||||
size.y = img.GetHeight();
|
||||
// Memory
|
||||
size_t n = size.x * size.y;
|
||||
if (n != old_n) {
|
||||
delete[] alpha;
|
||||
alpha = new Byte[n];
|
||||
}
|
||||
delete[] lefts; lefts = nullptr;
|
||||
delete[] rights; rights = nullptr;
|
||||
// Copy red chanel to alpha
|
||||
Byte* from = img.GetData(), *to = alpha;
|
||||
for (size_t i = 0 ; i < n ; ++i) {
|
||||
to[i] = from[3*i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void AlphaMask::setAlpha(Image& img) const {
|
||||
if (!alpha) return;
|
||||
set_alpha(img, alpha, size);
|
||||
if (!alpha) return;
|
||||
set_alpha(img, alpha, size);
|
||||
}
|
||||
|
||||
void AlphaMask::setAlpha(Bitmap& bmp) const {
|
||||
if (!alpha) return;
|
||||
Image img = bmp.ConvertToImage();
|
||||
setAlpha(img);
|
||||
bmp = Bitmap(img);
|
||||
if (!alpha) return;
|
||||
Image img = bmp.ConvertToImage();
|
||||
setAlpha(img);
|
||||
bmp = Bitmap(img);
|
||||
}
|
||||
|
||||
bool AlphaMask::isOpaque(int x, int y) const {
|
||||
if (x < 0 || y < 0 || x >= size.x || y >= size.y) return false;
|
||||
if (alpha) {
|
||||
return alpha[x + y * size.x] >= 20;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
if (x < 0 || y < 0 || x >= size.x || y >= size.y) return false;
|
||||
if (alpha) {
|
||||
return alpha[x + y * size.x] >= 20;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
bool AlphaMask::isOpaque(const RealPoint& p, const RealSize& resize) const {
|
||||
if (p.x < 0 || p.y < 0 || p.x >= resize.width || p.y >= resize.height) return false;
|
||||
if (alpha) {
|
||||
int x = (int)(p.x * size.x / resize.width);
|
||||
int y = (int)(p.y * size.y / resize.height);
|
||||
return alpha[x + y * size.x] >= 20;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
if (p.x < 0 || p.y < 0 || p.x >= resize.width || p.y >= resize.height) return false;
|
||||
if (alpha) {
|
||||
int x = (int)(p.x * size.x / resize.width);
|
||||
int y = (int)(p.y * size.y / resize.height);
|
||||
return alpha[x + y * size.x] >= 20;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// Do the points form a (counter??)clockwise angle?
|
||||
bool convex(const wxPoint& p, const wxPoint& q, const wxPoint& r) {
|
||||
return p.y*q.x - p.x*q.y - p.y*r.x + q.y*r.x + p.x*r.y - q.x*r.y > 0;
|
||||
return p.y*q.x - p.x*q.y - p.y*r.x + q.y*r.x + p.x*r.y - q.x*r.y > 0;
|
||||
}
|
||||
void make_convex(vector<wxPoint>& points) {
|
||||
while (points.size() > 2 &&
|
||||
!convex(points[points.size() - 3]
|
||||
,points[points.size() - 2]
|
||||
,points[points.size() - 1])) {
|
||||
points.erase(points.end() - 2);
|
||||
}
|
||||
while (points.size() > 2 &&
|
||||
!convex(points[points.size() - 3]
|
||||
,points[points.size() - 2]
|
||||
,points[points.size() - 1])) {
|
||||
points.erase(points.end() - 2);
|
||||
}
|
||||
}
|
||||
void add_convex_point(vector<wxPoint>& points, int x, int y) {
|
||||
points.push_back(wxPoint(x,y));
|
||||
make_convex(points);
|
||||
points.push_back(wxPoint(x,y));
|
||||
make_convex(points);
|
||||
}
|
||||
|
||||
void AlphaMask::convexHull(vector<wxPoint>& points) const {
|
||||
if (!alpha) throw InternalError(_("AlphaMask::convexHull"));
|
||||
// Left side, top to bottom
|
||||
int miny = size.y, maxy = -1, lastx = 0;
|
||||
for (int y = 0 ; y < size.y ; ++y) {
|
||||
for (int x = 0 ; x < size.x ; ++x) {
|
||||
if (alpha[x + y * size.x] >= 20) {
|
||||
// opaque pixel
|
||||
miny = min(miny,y);
|
||||
maxy = y;
|
||||
if (y == miny) {
|
||||
add_convex_point(points, x-1, y-1);
|
||||
}
|
||||
add_convex_point(points, x-1, y);
|
||||
lastx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (maxy == -1) return; // No image
|
||||
add_convex_point(points, lastx-1, maxy+1);
|
||||
// Right side, bottom to top
|
||||
for (int y = maxy ; y >= miny ; --y) {
|
||||
for (int x = size.x - 1 ; x >= 0 ; --x) {
|
||||
if (alpha[x + y * size.x] >= 20) {
|
||||
// opaque pixel
|
||||
if (y == maxy) {
|
||||
add_convex_point(points, x+1, y+1);
|
||||
}
|
||||
add_convex_point(points, x+1, y);
|
||||
lastx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
add_convex_point(points, lastx+1, miny-1);
|
||||
if (!alpha) throw InternalError(_("AlphaMask::convexHull"));
|
||||
// Left side, top to bottom
|
||||
int miny = size.y, maxy = -1, lastx = 0;
|
||||
for (int y = 0 ; y < size.y ; ++y) {
|
||||
for (int x = 0 ; x < size.x ; ++x) {
|
||||
if (alpha[x + y * size.x] >= 20) {
|
||||
// opaque pixel
|
||||
miny = min(miny,y);
|
||||
maxy = y;
|
||||
if (y == miny) {
|
||||
add_convex_point(points, x-1, y-1);
|
||||
}
|
||||
add_convex_point(points, x-1, y);
|
||||
lastx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (maxy == -1) return; // No image
|
||||
add_convex_point(points, lastx-1, maxy+1);
|
||||
// Right side, bottom to top
|
||||
for (int y = maxy ; y >= miny ; --y) {
|
||||
for (int x = size.x - 1 ; x >= 0 ; --x) {
|
||||
if (alpha[x + y * size.x] >= 20) {
|
||||
// opaque pixel
|
||||
if (y == maxy) {
|
||||
add_convex_point(points, x+1, y+1);
|
||||
}
|
||||
add_convex_point(points, x+1, y);
|
||||
lastx = x;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
add_convex_point(points, lastx+1, miny-1);
|
||||
}
|
||||
|
||||
Image AlphaMask::colorImage(const Color& color) const {
|
||||
Image image(size.x, size.y);
|
||||
fill_image(image, color);
|
||||
setAlpha(image);
|
||||
return image;
|
||||
Image image(size.x, size.y);
|
||||
fill_image(image, color);
|
||||
setAlpha(image);
|
||||
return image;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------------------------- : Contour Mask
|
||||
|
||||
void AlphaMask::loadRowSizes() const {
|
||||
if (lefts || !alpha) return;
|
||||
lefts = new int[size.y];
|
||||
rights = new int[size.y];
|
||||
// for each row: determine left and rightmost white pixel
|
||||
for (int y = 0 ; y < size.y ; ++y) {
|
||||
lefts[y] = size.x;
|
||||
rights[y] = 0;
|
||||
for (int x = 0 ; x < size.x ; ++x) {
|
||||
if (alpha[y * size.x + x] >= 128) { // white enough
|
||||
rights[y] = x;
|
||||
if (x < lefts[y]) lefts[y] = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (lefts || !alpha) return;
|
||||
lefts = new int[size.y];
|
||||
rights = new int[size.y];
|
||||
// for each row: determine left and rightmost white pixel
|
||||
for (int y = 0 ; y < size.y ; ++y) {
|
||||
lefts[y] = size.x;
|
||||
rights[y] = 0;
|
||||
for (int x = 0 ; x < size.x ; ++x) {
|
||||
if (alpha[y * size.x + x] >= 128) { // white enough
|
||||
rights[y] = x;
|
||||
if (x < lefts[y]) lefts[y] = x;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double AlphaMask::rowLeft (double y, const RealSize& resize) const {
|
||||
loadRowSizes();
|
||||
if (!lefts || y < 0 || y >= resize.height) {
|
||||
// no mask, or outside it
|
||||
return 0;
|
||||
}
|
||||
return lefts[(int)(y * size.y / resize.height)] * resize.width / size.x;
|
||||
loadRowSizes();
|
||||
if (!lefts || y < 0 || y >= resize.height) {
|
||||
// no mask, or outside it
|
||||
return 0;
|
||||
}
|
||||
return lefts[(int)(y * size.y / resize.height)] * resize.width / size.x;
|
||||
}
|
||||
|
||||
double AlphaMask::rowRight(double y, const RealSize& resize) const {
|
||||
loadRowSizes();
|
||||
if (!rights || y < 0 || y >= resize.height) {
|
||||
// no mask, or outside it
|
||||
return resize.width;
|
||||
}
|
||||
return rights[(int)(y * size.y / resize.height)] * resize.width / size.x;
|
||||
loadRowSizes();
|
||||
if (!rights || y < 0 || y >= resize.height) {
|
||||
// no mask, or outside it
|
||||
return resize.width;
|
||||
}
|
||||
return rights[(int)(y * size.y / resize.height)] * resize.width / size.x;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user