Since both shapes are being rendered with an opaque color, why not just render shape1 followed by shape3?

The problem you are running into with antialiasing is a common one and it is due to the fact that the two operations work independently to fill C (for fraction of coverage) of the pixel and then again to fill (1.0-C) of the pixel. Geometrically you can see that the two operations should be filling wholly separate parts of the pixel and so the new coverage should be a full 1.0, but the operations are done in isolation and so filling C of the pixel in the first operation leaves it C filled and (1.0-C) remaining from the original background color. The second operation then comes along and fills against the blended color and ends up leaving some of the background still showing:

        bg = original background color
        c1 = color of first fill operation
        ci = intermediate color after first fill operation
        c2 = color of second fill operation
        cf = final color
        C = coverage of first shape
        1-C = coverage of second, subtracted shape

First operation (fills the pixel with coverage C):

        ci = C * c1 + (1-C) * bg

Second operation (fills again with coverage 1-C):

        cf = (1-C) * c2 + (1-(1-C)) * ci
           = (1-C) * c2 + C * ci
           = (1-C) * c2 + C * C * c1 + C * (1-C) * bg

If the coverage was 0.5 then the background should still be contributing to 0.25 of the color of the pixel. Note also that the first color is also only contributing to 0.25 of the pixel and the second color is the only one with a proper contribution at 0.5 of the pixel.

The only workarounds are:

- Render the entire scene non-antialiased at a higher resolution and then use image subsampling in stages on the fully rendered image to downsample while blending to create a "full scene antialiasing" technique

- Render a fringe around the second operation so that it fully bleeds into its border pixels and then render the first operation on top of it so that it correctly replaces exactly the "C" portion of the pixel and leaves the remaining "1-C" portion set to the second color. (Someone already suggested this technique here, but I am adding a little to it by saying that it works better if you perform the second fill first with its fringe and then have the first fill done in AA mode on top of it.)

Hope that helps!

                        ...jim

davood wrote:
Hi,

In my application I'm creating new shape (Area) by subtracting a shape from
another one but when I turn on the antialias in rendering I face with a
white border around inner object. I'm not using composite because I need to
create the shape by subtracting. Is there any solution for this problem?
Here is a sample code,

private void drawTest(Graphics2D g2) {
        g2.setColor(Color.WHITE);
        g2.fillRect(0, 0, getWidth(), getHeight());
        
        Ellipse2D shape1 = new Ellipse2D.Double(150, 185, 150, 60);
        
        Shape shape3 = new Rectangle2D.Double(100, 100, 250, 250);
        Area area = new Area(shape3);
        area.subtract(new Area(shape1));
        
        g2.setColor(new Color(86 / 256f, 114 / 256f, 142 / 256f, 1f));
        g2.fill(area);

        g2.setColor(new Color(86 / 256f, 144 / 256f, 182 / 256f, 1f));
        g2.fill(shape1);
}
        


===========================================================================
To unsubscribe, send email to [EMAIL PROTECTED] and include in the body
of the message "signoff JAVA2D-INTEREST".  For general help, send email to
[EMAIL PROTECTED] and include in the body of the message "help".

Reply via email to