Antialized Fonts and other Drawing Stuff
Posted: Fri Mar 18, 2005 5:02 pm
i know there must be any way with the windows API, to draw smooth antialized fonts (without changing any gfx card settings by the user!).
someone an idea?
btw, is there any way to draw smooth antialized circles, lines? (maybe optional with blending effect?)
EDIT
Can someone convert this to use in PureBasic?
someone an idea?
btw, is there any way to draw smooth antialized circles, lines? (maybe optional with blending effect?)
EDIT
Can someone convert this to use in PureBasic?
Code: Select all
inline void BlendPixel(EFFECT_BMP *image,const int x0,const int y0,const int srccolor,int alpha){
int offs = y0*image->bmp_width + x0;
int destcolor = image->surface_bits[offs];
alpha &= 255;
int destred = 255*((destcolor>>16)&255)+
alpha*(((srccolor>>16)&255)-((destcolor>>16)&255));
int destgreen = 255*((destcolor>>8)&255)+
alpha*(((srccolor>>8)&255)-((destcolor>>8)&255));
int destblue = 255*(destcolor&255)+
alpha*((srccolor&255)-(destcolor&255));
destred = destred>>8;
destgreen = destgreen>>8;
destblue = destblue>>8;
image->surface_bits[offs]= destred<<16 | destgreen<<8 | destblue;
}//End BlendPixel
inline void BlendPixelClipped(EFFECT_BMP *image,const int x0,const int y0,const int srccolor,int alpha){
if ((x0<0) | (x0>=image->bmp_width) | (y0<0) | (y0>=image->bmp_height))return;
int offs = y0*image->bmp_width + x0;
int destcolor = image->surface_bits[offs];
alpha &= 255;
int destred = 255*((destcolor>>16)&255)+
alpha*(((srccolor>>16)&255)-((destcolor>>16)&255));
int destgreen = 255*((destcolor>>8)&255)+
alpha*(((srccolor>>8)&255)-((destcolor>>8)&255));
int destblue = 255*(destcolor&255)+
alpha*((srccolor&255)-(destcolor&255));
destred = destred>>8;
destgreen = destgreen>>8;
destblue = destblue>>8;
image->surface_bits[offs]= destred<<16 | destgreen<<8 | destblue;
}//End BlendPixelClipped
inline void Swap(int &a,int &b){
int temp = a;
a=b;
b=temp;
}
void AntialiasedLine(EFFECT_BMP *image,int x0, int y0, int x1, int y1, int Colour) {
y0=image->bmp_height-y0-1;
y1=image->bmp_height-y1-1;
int dx, dy, xDir;
if(y0>y1) {
Swap(y0,y1);
Swap(x0,x1);
}
BlendPixel(image,x0,y0, Colour,255); //First and last Pixels always get Set:
BlendPixel(image,x1,y1, Colour,255);
dx=x1-x0;
dy=y1-y0;
if(dx>=0) xDir=1;
else {
xDir=-1;
dx=-dx;
}
if(dx==0) { // Vertical line.
for(int i=0; i<(y1-y0); i++)
BlendPixel(image,x0,y0+i,Colour,255);
return;
}
if(dy==0) { // Horizontal line.
for(int i=0; i<(x1-x0)*xDir; i++)
BlendPixel(image,x0+i*xDir,y0,Colour,255);
return;
}
if(dx==dy) { // diagonal line.
for(int i=0; i<(x1-x0)*xDir; i++)
BlendPixel(image,x0+i*xDir,y0+i,Colour,255);
return;
}
// Line is not horizontal, diagonal, or vertical: use Wu Antialiasing:
int ErrorAcc=0;
int Transparency;
if(dy>dx) { // y-major line
int ErrorAdj=(dx<<16) / dy;
if(xDir<0) {
while(--dy) {
ErrorAcc+=ErrorAdj;
++y0;
x1=x0-(ErrorAcc>>16);
Transparency=(ErrorAcc>>8);
BlendPixel(image,x1 , y0, Colour,~Transparency);
BlendPixel(image,x1-1, y0, Colour,Transparency);
}
}else{
while(--dy) {
ErrorAcc+=ErrorAdj;
++y0;
x1=x0+(ErrorAcc>>16);
Transparency=(ErrorAcc>>8);
BlendPixel(image,x1 , y0, Colour,~Transparency);
BlendPixel(image,x1+1, y0, Colour,Transparency);
} }
}else{ // x-major line
int ErrorAdj=(dy<<16) / dx;
while(--dx) {
ErrorAcc+=ErrorAdj;
x0+=xDir;
y1=y0+(ErrorAcc>>16);
Transparency=(ErrorAcc>>8);
BlendPixel(image,x0 , y1, Colour,~Transparency);
BlendPixel(image,x0, y1+1, Colour,Transparency);
} }
}//End AntialiasedLine
void AntialiasedLineClipped(EFFECT_BMP *image,int x0, int y0, int x1, int y1, int Colour) {
y0=image->bmp_height-y0-1;
y1=image->bmp_height-y1-1;
int dx, dy, xDir;
if(y0>y1) {
Swap(y0,y1);
Swap(x0,x1);
}
BlendPixelClipped(image,x0,y0, Colour,255); //First and last Pixels always get Set:
BlendPixelClipped(image,x1,y1, Colour,255);
dx=x1-x0;
dy=y1-y0;
if(dx>=0) xDir=1;
else {
xDir=-1;
dx=-dx;
}
if(dx==0) { // Vertical line.
for(int i=0; i<(y1-y0); i++)
BlendPixelClipped(image,x0,y0+i,Colour,255);
return;
}
if(dy==0) { // Horizontal line.
for(int i=0; i<(x1-x0)*xDir; i++)
BlendPixelClipped(image,x0+i*xDir,y0,Colour,255);
return;
}
if(dx==dy) { // diagonal line.
for(int i=0; i<(x1-x0)*xDir; i++)
BlendPixelClipped(image,x0+i*xDir,y0+i,Colour,255);
return;
}
// Line is not horizontal, diagonal, or vertical: use Wu Antialiasing:
int ErrorAcc=0;
int Transparency;
if(dy>dx) { // y-major line
int ErrorAdj=(dx<<16) / dy;
if(xDir<0) {
while(--dy) {
ErrorAcc+=ErrorAdj;
++y0;
x1=x0-(ErrorAcc>>16);
Transparency=(ErrorAcc>>8);
BlendPixelClipped(image,x1 , y0, Colour,~Transparency);
BlendPixelClipped(image,x1-1, y0, Colour,Transparency);
}
}else{
while(--dy) {
ErrorAcc+=ErrorAdj;
++y0;
x1=x0+(ErrorAcc>>16);
Transparency=(ErrorAcc>>8);
BlendPixelClipped(image,x1 , y0, Colour,~Transparency);
BlendPixelClipped(image,x1+1, y0, Colour,Transparency);
} }
}else{ // x-major line
int ErrorAdj=(dy<<16) / dx;
while(--dx) {
ErrorAcc+=ErrorAdj;
x0+=xDir;
y1=y0+(ErrorAcc>>16);
Transparency=(ErrorAcc>>8);
BlendPixelClipped(image,x0 , y1, Colour,~Transparency);
BlendPixelClipped(image,x0, y1+1, Colour,Transparency);
} }
}//End AntialiasedLineClipped