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.
if (feather > rad) return 0;
Take the center point and radius, and construct a bounding
square that is the size of the diameter 2r
.
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.
fillrad = rad - feather;
Iterate through the bounding 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.
d = sqrt((cx - xp)*(cx - xp) + (cy - yp)*(cy - yp));
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 blend
amount.
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.
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.
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 powslope
flag is turned on.
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.
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
.
monolith_gfx_blend(tmp, clr, a, &tmp);
monolith_gfx_pixel_set(fb, xp, yp, tmp);
Update the new color.
prev | home | next