Download the updated Basic Antialias:
BasicAntialias11.zip-EDIT-
The 1.1 release fixes the reported bug. Or, at least, I hope so. You find this new Basic Antialias in the Effects->Object submenu.
I cannot say if Basic Antialias is better than Antialias. What I can say is that my design goals in writing it were 1) avoid side effects like shrink, grow, blur or outline, and 2) reduce aliasing in a basic way without having to spend time in fine tuning of the settings. Basic Antialias satisfies this goals, and also my personal needs. I hope you will find useful, too.
You find the code below. Now I can understand almost everything of it. My code is far from being perfect, it is redundant and not always does the right thing (it is almost impossible to note this, however). If you want to improve it but you can't understand it, please contact me and I'll try to explain.
I plan to release version 2.0 with support for trasparent objects in the future, but now I want to try developing other plugins.
Thanks,
Pyjo.
________________________What? After Feather and Antialias, another antialias plugin?
Well... sorry... this is my first plugin, I wanted to start with something simple and not too experimental.
Ok, but why
another Antialias plugin? Here is the answer: I noticed that some PdN users, including me, are not totally satisfied with existing antialias tools. I often used motion blur, which is not intended for this purpose, for removing aliasing effectively. So I took CodeLab and wrote this new plugin. Since I'm not a developer (and I don't know C#) it required me a lot of time, but eventually, pushing and kicking, my bare C code worked as expected (I hope that soon or later I'll understand how, too).
I created this plugin for personal use, but maybe that someone else will find it useful. Basic Antialias is basic in that it doesn't ask the user for any setting. It affects the border of "solid" shapes surrounded by trasparent pixels. It is useful when you copy and paste a selection in a new layer or when you fill a selection with something like clouds or gradient, as in this example:

(f you see no difference between the four moons, please put your nose close to the screen.)
The original picture is aliased. Feather and Antialias (with default settings) introduce a blur. Basic Antialias reduces aliasing without altering the sharpness of the border.
Here is another example:

The rose was selected with the magic wand from a photo, copied two times in a new layer and then Basic Antialias was applied to the second one.
To use this plugin dowload the .zip, put the extracted .dll file in the Effects folder and (re)start PdN. You'll find the tool in Effects>Contour submenu (is this the right menu for an antialias? Please give me a feedback).
If the plugin seems not to work, verify that the shape to be processed doesn't contain any partially trasparent pixel. Basic Antialias works only when it finds a totally trasparent pixel (alpha=0) near a not-trasparent-at-all pixel (alpha=255). If some antialias tool was previously used on the picture (note that paintbrush and other drawing tools have the antialias feature on by default), basic antialias won't do anything on it. Maybe this limitation will be removed in 2.0 version.
Bye,
Pyjo.
Code:
void Render(Surface dst, Surface src, Rectangle rect)
{
PdnRegion selectionRegion = EnvironmentParameters.GetSelection(src.Bounds);
Rectangle selection = this.EnvironmentParameters.GetSelection(src.Bounds).GetBoundsInt();
ColorBgra CurrentPixel;
for(int y = rect.Top; y < rect.Bottom; y++)
{
for (int x = rect.Left; x < rect.Right; x++)
{
if (selectionRegion.IsVisible(x, y))
{
CurrentPixel = src[x,y];
int i,j,p;
//VERTICAL
double x1,x2;
for (p=1;p>=-1;p-=2)
{
//Addition
if((x>selection.Left) && (x<selection.Right-1) && CurrentPixel.A==0&&src[x-p,y].A==255)
{
for(i=y;src[x,i].A==0 && src[x-p,i].A==255 && i<selection.Bottom-1;i++);
for(j=y;src[x,j].A==0 && src[x-p,j].A==255 && j>selection.Top;j--);
if(src[x,j].A==255&&y<=(i+j)/2) //bottom
{
x1=((double)y+(0.5))/(j-i+1)+(0.5)*(i+j)/(-j+i-1);
x2=((double)y-(0.5))/(j-i+1)+(0.5)*(i+j)/(-j+i-1);
CurrentPixel=src[x-p,y];
CurrentPixel.A=(byte)((x1+x2)*127);
}
if(src[x,i].A==255&&y>(i+j)/2) //top
{
x1=((double)y+(0.5))/(j-i+1)+(0.5)*(i+j)/(-j+i-1);
x2=((double)y-(0.5))/(j-i+1)+(0.5)*(i+j)/(-j+i-1);
CurrentPixel=src[x-p,y]; CurrentPixel.A=(byte)(255-(x1+x2)*127);
}
}
//Subtraction
if((x>selection.Left) && (x<selection.Right-1) && src[x,y].A==255&&src[x-p,y].A==0)
{
for(i=y;src[x,i].A==255 && src[x-p,i].A==0 && i<selection.Bottom-1;i++);
for(j=y; src[x,j].A==255 && src[x-p,j].A==0 && j>selection.Top;j--);
if(src[x,i].A==0&&y>(i+j)/2) //bottom
{
x1=((double)y+(0.5))/(j-i+1)+(0.5)*(i+j)/(-j+i-1);
x2=((double)y-(0.5))/(j-i+1)+(0.5)*(i+j)/(-j+i-1);
CurrentPixel.A+=(byte)((x1+x2)*127);
}
if(src[x,j].A==0 &&y<(i+j)/2) //top
{
x1=((double)y+(0.5))/(j-i+1)+(0.5)*(i+j)/(-j+i-1);
x2=((double)y-(0.5))/(j-i+1)+(0.5)*(i+j)/(-j+i-1);
CurrentPixel.A-=(byte)((x1+x2)*127);
}
}
}
//HORIZONTAL
double y1,y2;
for (p=1;p>=-1;p-=2)
{
//Subtraction
if((y>selection.Top) && (y<selection.Bottom-1) && CurrentPixel.A==255&&src[x,y-p].A==0)
{
for(i=x;src[i,y].A==255 && src[i,y-p].A<255 && i<selection.Right-1;i++);
for(j=x;src[j,y].A==255 && src[j,y-p].A<255 && j>selection.Left;j--);
if(src[j,y].A==0&&x<=(i+j)/2) //going up
{
y1=((double)x+(0.5))/(i-j-1)+(0.5)*(i+j)/(j-i+1);
y2=((double)x-(0.5))/(i-j-1)+(0.5)*(i+j)/(j-i+1);
if(x==((i+j)/2)) CurrentPixel.A=(byte)(255-((y1/2)*127));
else CurrentPixel.A+=(byte)((y1+y2)*127);
}
if(src[i,y].A==0 &&x>=(i+j)/2) //going down
{
y1=((double)x+(0.5))/(j-i+1)+(0.5)*(i+j)/(i-j-1);
y2=((double)x-(0.5))/(j-i+1)+(0.5)*(i+j)/(i-j-1);
if(x==((i+j)/2)) CurrentPixel.A=(byte)(255-((y2/2)*127));
else CurrentPixel.A+=(byte)((y1+y2)*127);
}
}
//Addition
if((y>selection.Top) && (y<selection.Bottom-1) && CurrentPixel.A==0&&src[x,y-p].A==255)
{
for(i=x;src[i,y].A==0 && src[i,y-p].A==255&& i<selection.Right-1;i++);
for(j=x;src[j,y].A==0 && src[j,y-p].A==255&& j>selection.Left;j--);
if(src[i,y].A==255&&x>=(i+j)/2) //going up
{
CurrentPixel=src[x,y-p];
y1=((double)x+(0.5))/(i-j-1)+(0.5)*(i+j)/(j-i+1);
y2=((double)x-(0.5))/(i-j-1)+(0.5)*(i+j)/(j-i+1);
if(x==((i+j)/2)) CurrentPixel.A=(byte)((y1/2)*127);
else CurrentPixel.A=(byte)((y1+y2)*127);
}
if(src[j,y].A==255&&x<=(i+j)/2) //going down
{
CurrentPixel=src[x,y-p];
y1=((double)x+(0.5))/(j-i+1)+(0.5)*(i+j)/(i-j-1);
y2=((double)x-(0.5))/(j-i+1)+(0.5)*(i+j)/(i-j-1);
if(x==((i+j)/2)) CurrentPixel.A=(byte)((y2/2)*127);else
CurrentPixel.A=(byte)((y1+y2)*127);
}
}
}
dst[x,y] = CurrentPixel;
}
}
}
}