This source file includes following definitions.
- mul255
- overmask_bgra
- overmask_bgra_const_run
- evg_bgra_fill_const
- evg_bgra_fill_const_a
- evg_bgra_fill_var
- evg_surface_clear_bgra
- overmask_bgrx
- overmask_bgrx_const_run
- evg_bgrx_fill_const
- evg_bgrx_fill_const_a
- evg_bgrx_fill_var
- overmask_rgbx
- overmask_rgbx_const_run
- evg_rgbx_fill_const
- evg_rgbx_fill_const_a
- evg_rgbx_fill_var
- evg_surface_clear_rgbx
- overmask_rgba
- overmask_rgba_const_run
- evg_rgba_fill_const
- evg_rgba_fill_const_a
- evg_rgba_fill_var
- evg_rgba_fill_erase
- evg_surface_clear_rgba
#include "rast_soft.h"
static GFINLINE s32
mul255(s32 a, s32 b)
{
return ((a+1) * b) >> 8;
}
static void overmask_bgra(u32 src, u8 *dst, u32 alpha)
{
s32 srca = (src >> 24) & 0xff;
s32 srcr = (src >> 16) & 0xff;
s32 srcg = (src >> 8) & 0xff;
s32 srcb = (src >> 0) & 0xff;
s32 dsta = dst[3];
srca = mul255(srca, alpha);
if (dsta) {
s32 dstr = dst[1];
s32 dstg = dst[1];
s32 dstb = dst[0];
dst[0] = mul255(srca, srcb - dstb) + dstb;
dst[1] = mul255(srca, srcg - dstg) + dstg;
dst[2] = mul255(srca, srcr - dstr) + dstr;
dst[3] = mul255(srca, srca) + mul255(255-srca, dsta);
} else {
dst[0] = srcb;
dst[1] = srcg;
dst[2] = srcr;
dst[3] = srca;
}
}
static void overmask_bgra_const_run(u32 src, u8 *dst, s32 dst_pitch_x, u32 count)
{
s32 srca = (src >> 24) & 0xff;
s32 srcr = (src >> 16) & 0xff;
s32 srcg = (src >> 8) & 0xff;
s32 srcb = (src >> 0) & 0xff;
while (count) {
s32 dsta = dst[3];
if (dsta) {
s32 dstb = dst[0];
s32 dstg = dst[1];
s32 dstr = dst[2];
dst[0] = mul255(srca, srcb - dstb) + dstb;
dst[1] = mul255(srca, srcg - dstg) + dstg;
dst[2] = mul255(srca, srcr - dstr) + dstr;
dst[3] = mul255(srca, srca) + mul255(255-srca, dsta);
} else {
dst[0] = srcr;
dst[1] = srcg;
dst[2] = srcr;
dst[3] = srca;
}
dst += dst_pitch_x;
count--;
}
}
void evg_bgra_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u32 col = surf->fill_col;
u32 a, fin, col_no_a;
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
s32 i, x;
u32 len;
u8 col_a, col_r, col_g, col_b;
col_a = GF_COL_A(col);
col_r = GF_COL_R(col);
col_g = GF_COL_G(col);
col_b = GF_COL_B(col);
col_no_a = col & 0x00FFFFFF;
for (i=0; i<count; i++) {
x = spans[i].x * surf->pitch_x;
len = spans[i].len;
if (spans[i].coverage != 0xFF) {
a = mul255(0xFF, spans[i].coverage);
fin = (a<<24) | col_no_a;
overmask_bgra_const_run(fin, dst + x, surf->pitch_x, len);
} else {
while (len--) {
dst[x] = col_b;
dst[x+1] = col_g;
dst[x+2] = col_r;
dst[x+3] = col_a;
x += surf->pitch_x;
}
}
}
}
void evg_bgra_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u32 col = surf->fill_col;
u32 a, fin, col_no_a;
s32 i;
a = (col>>24)&0xFF;
col_no_a = col & 0x00FFFFFF;
for (i=0; i<count; i++) {
fin = mul255(a, spans[i].coverage);
fin = (fin<<24) | col_no_a;
overmask_bgra_const_run(fin, dst + surf->pitch_x*spans[i].x, surf->pitch_x, spans[i].len);
}
}
void evg_bgra_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u8 spanalpha, col_a;
s32 i, x;
u32 len;
u32 *col, _col;
for (i=0; i<count; i++) {
len = spans[i].len;
spanalpha = spans[i].coverage;
surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len);
x = spans[i].x * surf->pitch_x;
col = surf->stencil_pix_run;
while (len--) {
_col = *col;
col_a = GF_COL_A(_col);
if (col_a) {
if ((spanalpha!=0xFF) || (col_a != 0xFF)) {
overmask_bgra(*col, (dst + x) , spanalpha);
} else {
dst[x] = GF_COL_B(_col);
dst[x+1] = GF_COL_G(_col);
dst[x+2] = GF_COL_R(_col);
dst[x+3] = col_a;
}
}
col++;
x += surf->pitch_x;
}
}
}
GF_Err evg_surface_clear_bgra(GF_SURFACE surf, GF_IRect rc, GF_Color col)
{
u8 *data;
u8 col_a, col_b, col_g, col_r;
u32 x, y, w, h, sx, sy;
s32 st;
Bool use_memset;
EVGSurface *_this = (EVGSurface *)surf;
st = _this->pitch_y;
col_a = GF_COL_A(col);
col_r = GF_COL_R(col);
col_g = GF_COL_G(col);
col_b = GF_COL_B(col);
h = rc.height;
w = rc.width;
sx = rc.x;
sy = rc.y;
use_memset = GF_FALSE;
if (_this->pitch_x !=4) use_memset = GF_FALSE;
else if (!col_a) use_memset = GF_TRUE;
else if ((col_a==col_r) && (col_a==col_g) && (col_a==col_b)) use_memset = GF_TRUE;
if (!use_memset) {
for (y = 0; y < h; y++) {
data = (u8 *) _this ->pixels + (sy+y)* st + _this->pitch_x*sx;
for (x = 0; x < w; x++) {
data[0] = col_b;
data[1] = col_g;
data[2] = col_r;
data[3] = col_a;
data += _this->pitch_x;
}
}
} else {
u32 sw = 4*w;
for (y = 0; y < h; y++) {
memset(_this ->pixels + (sy+y)* st + _this->pitch_x * sx, col_a, sizeof(char)*sw);
}
}
return GF_OK;
}
static void overmask_bgrx(u32 src, u8 *dst, u32 alpha)
{
s32 srca = (src >> 24) & 0xff;
s32 srcr = (src >> 16) & 0xff;
s32 srcg = (src >> 8) & 0xff;
s32 srcb = (src >> 0) & 0xff;
s32 dstb = dst[0];
s32 dstg = dst[1];
s32 dstr = dst[2];
srca = mul255(srca, alpha);
dst[0] = mul255(srca, srcb - dstb) + dstb;
dst[1] = mul255(srca, srcg - dstg) + dstg;
dst[2] = mul255(srca, srcr - dstr) + dstr;
dst[3] = 0xFF;
}
GFINLINE static void overmask_bgrx_const_run(u32 src, u8 *dst, s32 dst_pitch_x, u32 count)
{
s32 srca = (src>>24) & 0xff;
u32 srcr = mul255(srca, ((src >> 16) & 0xff)) ;
u32 srcg = mul255(srca, ((src >> 8) & 0xff)) ;
u32 srcb = mul255(srca, ((src) & 0xff)) ;
u32 inva = 1 + 0xFF - srca;
while (count) {
dst[0] = srcb + ((inva*dst[0])>>8);
dst[1] = srcg + ((inva*dst[1])>>8);
dst[2] = srcr + ((inva*dst[2])>>8);
dst[3] = 0xFF;
dst += dst_pitch_x;
count--;
}
}
void evg_bgrx_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u32 col = surf->fill_col;
u32 fin, col_no_a, spana;
u8 col_r, col_g, col_b;
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
s32 i, x;
u32 len;
col_no_a = col & 0x00FFFFFF;
col_r = GF_COL_R(col);
col_g = GF_COL_G(col);
col_b = GF_COL_B(col);
for (i=0; i<count; i++) {
spana = spans[i].coverage;
x = spans[i].x * surf->pitch_x;
len = spans[i].len;
if (spana != 0xFF) {
fin = (spana<<24) | col_no_a;
overmask_bgrx_const_run(fin, dst + x, surf->pitch_x, len);
} else {
while (len--) {
dst[x] = col_b;
dst[x+1] = col_g;
dst[x+2] = col_r;
dst[x+3] = 0xFF;
x += surf->pitch_x;
}
}
}
}
void evg_bgrx_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u32 col = surf->fill_col;
u32 a, fin, col_no_a;
s32 i;
a = (col>>24)&0xFF;
col_no_a = col & 0x00FFFFFF;
for (i=0; i<count; i++) {
fin = mul255(a, spans[i].coverage);
fin = (fin<<24) | col_no_a;
overmask_bgrx_const_run(fin, dst + surf->pitch_x*spans[i].x, surf->pitch_x, spans[i].len);
}
}
void evg_bgrx_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u8 spanalpha, col_a;
s32 i, x;
u32 len;
u32 *col;
for (i=0; i<count; i++) {
len = spans[i].len;
spanalpha = spans[i].coverage;
surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len);
col = surf->stencil_pix_run;
x = spans[i].x * surf->pitch_x;
while (len--) {
u32 _col = *col;
col_a = GF_COL_A(_col);
if (col_a) {
if ((spanalpha!=0xFF) || (col_a != 0xFF)) {
overmask_bgrx(*col, dst+x, spanalpha);
} else {
dst[x] = GF_COL_B(_col);
dst[x+1] = GF_COL_G(_col);
dst[x+2] = GF_COL_R(_col);
dst[x+3] = 0xFF;
}
}
col++;
x += surf->pitch_x;
}
}
}
static void overmask_rgbx(u32 src, u8 *dst, u32 alpha)
{
s32 srca = (src >> 24) & 0xff;
s32 srcr = (src >> 16) & 0xff;
s32 srcg = (src >> 8) & 0xff;
s32 srcb = (src >> 0) & 0xff;
s32 dstr = dst[0];
s32 dstg = dst[1];
s32 dstb = dst[2];
srca = mul255(srca, alpha);
dst[0] = mul255(srca, srcr - dstr) + dstr;
dst[1] = mul255(srca, srcg - dstg) + dstg;
dst[2] = mul255(srca, srcb - dstb) + dstb;
dst[3] = 0xFF;
}
GFINLINE static void overmask_rgbx_const_run(u32 src, u8 *dst, s32 dst_pitch_x, u32 count)
{
s32 srca = (src>>24) & 0xff;
u32 srcr = mul255(srca, ((src >> 16) & 0xff)) ;
u32 srcg = mul255(srca, ((src >> 8) & 0xff)) ;
u32 srcb = mul255(srca, ((src) & 0xff)) ;
u32 inva = 1 + 0xFF - srca;
while (count) {
dst[0] = srcr + ((inva*dst[0])>>8);
dst[1] = srcg + ((inva*dst[1])>>8);
dst[2] = srcb + ((inva*dst[2])>>8);
dst += dst_pitch_x;
count--;
}
}
void evg_rgbx_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u32 col = surf->fill_col;
u32 fin, col_no_a, spana;
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u8 r, g, b;
s32 i, x;
u32 len;
col_no_a = col & 0x00FFFFFF;
r = GF_COL_R(col);
g = GF_COL_G(col);
b = GF_COL_B(col);
for (i=0; i<count; i++) {
spana = spans[i].coverage;
x = spans[i].x * surf->pitch_x;
len = spans[i].len;
if (spana != 0xFF) {
fin = (spana<<24) | col_no_a;
overmask_rgbx_const_run(fin, dst + x, surf->pitch_x, len);
} else {
while (len--) {
dst[x] = r;
dst[x+1] = g;
dst[x+2] = b;
dst[x+3] = 0xFF;
x += surf->pitch_x;
}
}
}
}
void evg_rgbx_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u32 col = surf->fill_col;
u32 a, fin, col_no_a;
s32 i;
a = (col>>24)&0xFF;
col_no_a = col & 0x00FFFFFF;
for (i=0; i<count; i++) {
fin = mul255(a, spans[i].coverage);
fin = (fin<<24) | col_no_a;
overmask_rgbx_const_run(fin, dst + surf->pitch_x*spans[i].x, surf->pitch_x, spans[i].len);
}
}
void evg_rgbx_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u8 spanalpha, col_a;
s32 i, x;
u32 len;
u32 *col, _col;
for (i=0; i<count; i++) {
len = spans[i].len;
spanalpha = spans[i].coverage;
surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len);
col = surf->stencil_pix_run;
x = spans[i].x * surf->pitch_x;
while (len--) {
_col = *col;
col_a = GF_COL_A(_col);
if (col_a) {
if ((spanalpha!=0xFF) || (col_a != 0xFF)) {
overmask_rgbx(*col, dst+x, spanalpha);
} else {
dst[x] = GF_COL_R(_col);
dst[x+1] = GF_COL_G(_col);
dst[x+2] = GF_COL_B(_col);
dst[x+3] = 0xFF;
}
}
col++;
x += surf->pitch_x;
}
}
}
GF_Err evg_surface_clear_rgbx(GF_SURFACE surf, GF_IRect rc, GF_Color col)
{
u32 x, y, w, h, sx, sy;
u8 r,g,b;
s32 st;
EVGSurface *_this = (EVGSurface *)surf;
st = _this->pitch_x;
h = rc.height;
w = rc.width;
sx = rc.x;
sy = rc.y;
r = GF_COL_R(col);
g = GF_COL_G(col);
b = GF_COL_B(col);
for (y = 0; y < h; y++) {
u8 *data = (u8 *) _this ->pixels + (y + sy) * _this->pitch_y + st*sx;
for (x = 0; x < w; x++) {
data[0] = r;
data[1] = g;
data[2] = b;
data[3] = 0xFF;
data += st;
}
}
return GF_OK;
}
GFINLINE static void overmask_rgba(u32 src, u8 *dst, u32 alpha)
{
u8 srca = GF_COL_A(src);
u8 srcr = GF_COL_R(src);
u8 srcg = GF_COL_G(src);
u8 srcb = GF_COL_B(src);
u8 dsta = dst[3];
srca = mul255(srca, alpha);
if (dsta && (srca!=0xFF) ) {
u8 final_a;
u8 dstr = dst[0];
u8 dstg = dst[1];
u8 dstb = dst[2];
final_a = dsta + srca - mul255(dsta, srca);
if (final_a) {
dst[0] = (u8) ((srcr*srca + dstr*(dsta-srca)) / final_a);
dst[1] = (u8) ((srcg*srca + dstg*(dsta-srca)) / final_a);
dst[2] = (u8) ((srcb*srca + dstb*(dsta-srca)) / final_a);
dst[3] = final_a;
} else {
assert(0);
}
} else {
dst[0] = srcr;
dst[1] = srcg;
dst[2] = srcb;
dst[3] = srca;
}
}
GFINLINE static void overmask_rgba_const_run(u32 src, u8 *dst, s32 dst_pitch_x, u32 count)
{
u8 srca = GF_COL_A(src);
u8 srcr = GF_COL_R(src);
u8 srcg = GF_COL_G(src);
u8 srcb = GF_COL_B(src);
while (count) {
u8 dsta = dst[3];
if ((dsta != 0) && (srca != 0xFF)) {
u8 final_a;
u8 dstr = dst[0];
u8 dstg = dst[1];
u8 dstb = dst[2];
final_a = dsta + srca - mul255(dsta, srca);
if (final_a) {
dst[0] = (u8) ((srcr*srca + dstr*(dsta-srca)) / final_a);
dst[1] = (u8) ((srcg*srca + dstg*(dsta-srca)) / final_a);
dst[2] = (u8) ((srcb*srca + dstb*(dsta-srca)) / final_a);
dst[3] = final_a;
} else {
assert(0);
}
} else {
dst[0] = srcr;
dst[1] = srcg;
dst[2] = srcb;
dst[3] = srca;
}
dst+=dst_pitch_x;
count--;
}
}
void evg_rgba_fill_const(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u32 col = surf->fill_col;
u32 new_a, fin, col_no_a;
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u8 *p;
s32 i;
u32 len;
col_no_a = col & 0x00FFFFFF;
for (i=0; i<count; i++) {
p = dst + spans[i].x*surf->pitch_x;
len = spans[i].len;
new_a = spans[i].coverage;
fin = (new_a<<24) | col_no_a;
overmask_rgba_const_run(fin, p, surf->pitch_x, len);
}
}
void evg_rgba_fill_const_a(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u32 a, fin, col_no_a;
s32 i;
a = GF_COL_A(surf->fill_col);
col_no_a = surf->fill_col & 0x00FFFFFF;
for (i=0; i<count; i++) {
fin = mul255(a, spans[i].coverage);
fin = (fin<<24) | col_no_a;
overmask_rgba_const_run(fin, dst + spans[i].x*surf->pitch_x, surf->pitch_x, spans[i].len);
}
}
void evg_rgba_fill_var(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u8 *p;
u8 spanalpha;
s32 i;
u32 len;
u32 *col;
for (i=0; i<count; i++) {
p = dst + spans[i].x * surf->pitch_x;
len = spans[i].len;
spanalpha = spans[i].coverage;
surf->sten->fill_run(surf->sten, surf, spans[i].x, y, len);
col = surf->stencil_pix_run;
while (len--) {
overmask_rgba(*col, p, spanalpha);
col++;
p += surf->pitch_x;
}
}
}
void evg_rgba_fill_erase(s32 y, s32 count, EVG_Span *spans, EVGSurface *surf)
{
u8 *dst = (u8 *) surf->pixels + y * surf->pitch_y;
u8 *p;
s32 i;
u32 len;
for (i=0; i<count; i++) {
p = dst + spans[i].x*surf->pitch_x;
len = spans[i].len;
if (spans[i].coverage != 0xFF) {
} else {
while (len--) {
*(u32 *)p = 0;
p += surf->pitch_x;
}
}
}
}
GF_Err evg_surface_clear_rgba(GF_SURFACE surf, GF_IRect rc, GF_Color col)
{
u8 *data;
u8 a, r, g, b;
u32 x, y, w, h, sy;
s32 st;
Bool use_memset;
EVGSurface *_this = (EVGSurface *)surf;
st = _this->pitch_y;
h = rc.height;
w = rc.width;
sy = rc.y;
if (sy+h > _this->height) {
h = _this->height - sy;
}
if (rc.x + w > _this->width) {
w = _this->width - rc.x;
}
a = GF_COL_A(col);
r = GF_COL_R(col);
g = GF_COL_G(col);
b = GF_COL_B(col);
use_memset = GF_FALSE;
if (_this->pitch_x !=4) use_memset = GF_FALSE;
else if (!a) use_memset = GF_TRUE;
else if ((a==r) && (a==g) && (a==b)) use_memset = GF_TRUE;
if (!use_memset) {
for (y = 0; y < h; y++) {
data = (u8 *) _this ->pixels + (sy+y)* st + _this->pitch_x * rc.x;
for (x = 0; x < w; x++) {
*(data) = r;
*(data+1) = g;
*(data+2) = b;
*(data+3) = a;
data += 4;
}
}
} else {
u32 sw = 4*w;
for (y = 0; y < h; y++) {
memset(_this ->pixels + (sy+y)* st + _this->pitch_x * rc.x, a, sizeof(char)*sw);
}
}
return GF_OK;
}