Commit b15ade3e authored by twanvl's avatar twanvl

Added convex hull function to ContourMask for drawing nicer borders around masked fields

parent bb5b564f
...@@ -151,6 +151,9 @@ class AlphaMask : public IntrusivePtrBase<AlphaMask> { ...@@ -151,6 +151,9 @@ class AlphaMask : public IntrusivePtrBase<AlphaMask> {
/// Is the given location fully transparent? /// Is the given location fully transparent?
bool isTransparent(int x, int y) const; bool isTransparent(int x, int y) const;
/// Determine a convex hull polygon *around* the mask
void convexHull(vector<wxPoint>& points) const;
/// Size of the mask /// Size of the mask
wxSize size; wxSize size;
private: private:
......
...@@ -41,7 +41,61 @@ void AlphaMask::setAlpha(Bitmap& bmp) const { ...@@ -41,7 +41,61 @@ void AlphaMask::setAlpha(Bitmap& bmp) const {
bool AlphaMask::isTransparent(int x, int y) const { bool AlphaMask::isTransparent(int x, int y) const {
if (x < 0 || y > 0 || x >= size.x || y >= size.y) return false; if (x < 0 || y > 0 || x >= size.x || y >= size.y) return false;
return alpha[x + y * size.GetWidth()] < 20; return alpha[x + y * size.x] < 20;
}
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;
}
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);
}
}
void AlphaMask::convexHull(vector<wxPoint>& points) const {
// Left side
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) {
points.push_back(wxPoint(x-1,y-1));
}
points.push_back(wxPoint(x-1,y));
make_convex(points);
lastx = x;
break;
}
}
}
if (maxy == -1) return; // No image
points.push_back(wxPoint(lastx-1,maxy+1));
make_convex(points);
// Right side
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) {
points.push_back(wxPoint(x+1,y+1));
make_convex(points);
}
points.push_back(wxPoint(x+1,y));
make_convex(points);
lastx = x;
break;
}
}
}
points.push_back(wxPoint(lastx+1,miny-1));
make_convex(points);
} }
// ----------------------------------------------------------------------------- : ContourMask // ----------------------------------------------------------------------------- : ContourMask
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment