2. Overview

The feather amount is the size in pixels of the outer edge fuzz. This amount cannot be greater than the radius itself, and will return early if this isn't true.

<<check_bounds>>=
if (feather > rad) return 0;

Take the center point and radius, and construct a bounding square that is the size of the diameter 2r.

<<create_bounding_box>>=
sz = floor(rad * 2);
xs = floor(cx - rad);
ys = floor(cy - rad);

The feather amount is subtracted from the main radius to get the full-color radius amount, known as fillrad. Any point within this region will be painted a full color with no feathering.

<<calculate_fillrad>>=
fillrad = rad - feather;

Iterate through the bounding box.

<<iterate_through_box>>=
for (y = 0; y < sz; y++) {
    for (x = 0; x < sz; x++) {
        float d;
        int xp, yp;
        xp = xs + x;
        yp = ys + y;
<<calculate_distance>>
<<check_and_draw>>
    }
}

A drawing operation will only occur if the point is within the radius of the center point. Cue the euclidean distance formula to get this value.

<<calculate_distance>>=
d = sqrt((cx - xp)*(cx - xp) + (cy - yp)*(cy - yp));
<<check_and_draw>>=
if (d < rad) {
    if (d < fillrad) {
<<fill>>
    } else {
<<feather>>
    }
}

Another distance check is done inside the first one to determine what kind of drawing operation will happen. A distance less than fillrad will be filled with a solid color, otherwise feathering will be applied.

Fill will blend in solid color based on the global blendamount.

<<fill>>=
monolith_pixel tmp;
float a;
int rc;

rc = monolith_gfx_pixel_get(fb, xp, yp, &tmp);
if (!rc) continue;
a = blend;
monolith_gfx_blend(tmp, clr, a, &tmp);
monolith_gfx_pixel_set(fb, xp, yp, tmp);

Feathering is a matter of calculating an intensity based on distance from the center, and blending that color in with the global blend amount.

<<feather>>=
monolith_pixel tmp;
float a;
int rc;
rc = monolith_gfx_pixel_get(fb, xp, yp, &tmp);
if (!rc) continue;
<<calculate_intensity>>
<<powslope>>
<<clamp_values>>
<<blend_in_color>>

The feathering amount is a value that represents the total feathering distance. The total distance is subtracted from the fillrad distance to get how much this value is normalized to be between 0 and 1, and then inverted.

<<calculate_intensity>>=
a = ((d - fillrad) / feather);
a = 1 - a;


Optionally, one can enable a squared slope, which produces a much softer outline. This only happens if the powslopeflag is turned on.

<<powslope>>=
if (powslope) a *= a;

Clamp the values at 0 and 1 to prevent any strange behavior that could have been introduced with powslope or anything else.

<<clamp_values>>=
if (a < 0) a = 0;
if (a > 1) a = 1;

Aqcuire the color of the current position in the framebuffer, and blend the new color using monolith_gfx_blend.

<<blend_in_color>>=
monolith_gfx_blend(tmp, clr, a, &tmp);
monolith_gfx_pixel_set(fb, xp, yp, tmp);

Update the new color.



prev | home | next