Subject:
Antialias
From:
Peter Hartshorn ####@####.####
Date:
6 Dec 2001 00:53:35 -0000
Message-Id: <20011206115025.A9169@helios.devel.igelaus.com.au>
Hello all,
I've been doing some work with antialias support in nxzilla and I
decided to do some improvements(?).
Basically the antialiasing was achieved by creating a ramp from bg
to fg. This was ok if the bg was known. The problem arrises when we are
writing text over a background that is either an unknown color, or is varying
(ie an image).
The solution I found was to create a ramp not from bg to fg, but from
0 to 0xff. Then, when we are drawing the image, we firstly get a copy of the
area which we are drawing onto, and using simple alpha blending we blend
the fg color into the copy based on the ramp value (0 = none, 255 = all).
Attached is a patch that does this, and hopefully does not increase
the overhead of text drawing too much.
Also, I have created a screenshot of nxzilla running with antialiased
fonts and standard gtk mozilla for a side by side (slightly overlapped actually)
comparison. The image is not attached (approx 280KB) but you can see it at
http://nxzilla.tuxia.org/antialias.png
From Peter Hartshorn
####@####.####
? engine/.depend
Index: engine/devfont.c
===================================================================
RCS file: /cvsroot/extra-libs/microwin/src/engine/devfont.c,v
retrieving revision 1.10
diff -u -r1.10 devfont.c
--- engine/devfont.c 2001/11/29 03:19:53 1.10
+++ engine/devfont.c 2001/12/06 00:31:16
@@ -1197,12 +1197,13 @@
/* Render a single glyph*/
static void
drawchar(PMWFREETYPEFONT pf, PSD psd, TT_Glyph glyph, int x_offset,
- int y_offset)
+ int y_offset, MWPIXELVAL color)
{
TT_F26Dot6 xmin, ymin, xmax, ymax, x, y, z;
unsigned char *src, *srcptr;
MWPIXELVAL *dst, *dstptr;
MWPIXELVAL *bitmap;
+ unsigned char r1, g1, b1;
int size, width, height;
TT_Outline outline;
TT_BBox bbox;
@@ -1263,14 +1264,35 @@
src = (char *) Raster.bitmap;
dst = bitmap + (size - width);
+ GdReadArea(psd, x_offset + xmin, y_offset - (ymin + height), width, height,
+ bitmap);
+
+ r1 = PIXEL2RED(color);
+ g1 = PIXEL2GREEN(color);
+ b1 = PIXEL2BLUE(color);
+
for (y = ymin; y < ymax; y++) {
srcptr = src;
dstptr = dst;
for (x = xmin; x < xmax; x++) {
- if (pf->fontattr&MWTF_ANTIALIAS)
- *dstptr++ = gray_palette[(int) *srcptr];
- else {
+ if (pf->fontattr&MWTF_ANTIALIAS) {
+ MWPIXELVAL bg_color, c;
+ OUTPIXELVAL gp;
+ unsigned char r2, g2, b2;
+ bg_color = *dstptr;
+ r2 = PIXEL2RED(bg_color);
+ g2 = PIXEL2GREEN(bg_color);
+ b2 = PIXEL2BLUE(bg_color);
+
+ gp = gray_palette[(int)*srcptr];
+ c = RGB2PIXEL(
+ (r1*gp/255) + (r2*(255-gp)/255),
+ (g1*gp/255) + (g2*(255-gp)/255),
+ (b1*gp/255) + (b2*(255-gp)/255)
+ );
+ *dstptr++ = c;
+ } else {
for(z=0;
z <= ((xmax-x-1) < 7 ? (xmax-x-1) : 7);
z++) {
@@ -1359,7 +1381,7 @@
if (pf->fontattr&MWTF_ANTIALIAS) {
TT_Set_Raster_Gray_Palette (engine, virtual_palette);
- alphablend(psd, gray_palette, gr_foreground, gr_background,
+ alphablend(psd, gray_palette, 0xff, 0x0,
blend, 5);
}
@@ -1391,7 +1413,7 @@
x += compute_kernval(pf, curchar) / 64;
}
- drawchar(pf, psd, pf->glyph, x, y);
+ drawchar(pf, psd, pf->glyph, x, y, gr_foreground);
if (pf->fontrotation) {
vec_x = metrics.advance;