#ifndef _RASOPS_BITOPS_H_
#define _RASOPS_BITOPS_H_ 1
#if RASOPS_DEPTH == 1
#define PIXEL_SHIFT 0
#elif RASOPS_DEPTH == 2
#define PIXEL_SHIFT 1
#elif RASOPS_DEPTH == 4
#define PIXEL_SHIFT 2
#else
#error "Depth not supported"
#endif
#define NAME(name) NAME1(RASOPS_DEPTH, name)
#define NAME1(depth, name) NAME2(depth, name)
#define NAME2(depth, name) rasops ## depth ## _ ## name
static void
NAME(erasecols)(void *cookie, int row, int col, int num, long attr)
{
struct rasops_info *ri = (struct rasops_info *)cookie;
int height, cnt;
uint32_t bg, lbg, rbg, lmask, rmask, tmp;
uint32_t *dp, *rp, *hp;
hp = NULL;
#ifdef RASOPS_CLIPPING
if ((unsigned)row >= (unsigned)ri->ri_rows)
return;
if (col < 0) {
num += col;
col = 0;
}
if (col + num > ri->ri_cols)
num = ri->ri_cols - col;
if (num <= 0)
return;
#endif
height = ri->ri_font->fontheight;
col *= ri->ri_font->fontwidth << PIXEL_SHIFT;
num *= ri->ri_font->fontwidth << PIXEL_SHIFT;
rp = (uint32_t *)(ri->ri_bits + row*ri->ri_yscale + ((col >> 3) & ~3));
if (ri->ri_hwbits)
hp = (uint32_t *)(ri->ri_hwbits + row*ri->ri_yscale +
((col >> 3) & ~3));
col &= 31;
bg = ATTR_BG(ri, attr);
if (col + num <= 32) {
lmask = ~rasops_pmask[col][num & 31];
bg &= ~lmask;
while (height--) {
tmp = (*rp & lmask) | bg;
*rp = tmp;
if (ri->ri_hwbits) {
*hp = tmp;
DELTA(hp, ri->ri_stride, uint32_t *);
}
DELTA(rp, ri->ri_stride, uint32_t *);
}
} else {
lmask = rasops_rmask[col];
rmask = rasops_lmask[(col + num) & 31];
if (lmask)
num = (num - (32 - col)) >> 5;
else
num = num >> 5;
lbg = bg & ~lmask;
rbg = bg & ~rmask;
while (height--) {
dp = rp;
if (lmask) {
*dp = (*dp & lmask) | lbg;
dp++;
}
for (cnt = num; cnt > 0; cnt--)
*dp++ = bg;
if (rmask)
*dp = (*dp & rmask) | rbg;
if (ri->ri_hwbits) {
memcpy(hp, rp, ((lmask != 0) + num +
(rmask != 0)) << 2);
DELTA(hp, ri->ri_stride, uint32_t *);
}
DELTA(rp, ri->ri_stride, uint32_t *);
}
}
}
static void
NAME(do_cursor)(struct rasops_info *ri)
{
int row, col, height, width, cnt;
uint32_t lmask, rmask, tmp;
uint32_t *dp, *rp, *hp;
hp = NULL;
row = ri->ri_crow;
col = ri->ri_ccol * ri->ri_font->fontwidth << PIXEL_SHIFT;
height = ri->ri_font->fontheight;
width = ri->ri_font->fontwidth << PIXEL_SHIFT;
rp = (uint32_t *)(ri->ri_bits + row * ri->ri_yscale +
((col >> 3) & ~3));
if (ri->ri_hwbits)
hp = (uint32_t *)(ri->ri_hwbits + row * ri->ri_yscale +
((col >> 3) & ~3));
col &= 31;
if (col + width <= 32) {
lmask = rasops_pmask[col][width & 31];
while (height--) {
tmp = *rp ^ lmask;
*rp = tmp;
if (ri->ri_hwbits) {
*hp = tmp;
DELTA(hp, ri->ri_stride, uint32_t *);
}
DELTA(rp, ri->ri_stride, uint32_t *);
}
} else {
lmask = ~rasops_rmask[col];
rmask = ~rasops_lmask[(col + width) & 31];
if (lmask != -1)
width = (width - (32 - col)) >> 5;
else
width = width >> 5;
while (height--) {
dp = rp;
if (lmask != -1)
*dp++ ^= lmask;
for (cnt = width; cnt; cnt--) {
*dp = ~*dp;
dp++;
}
if (rmask != -1)
*dp ^= rmask;
if (ri->ri_hwbits) {
memcpy(hp, rp, ((lmask != -1) + width +
(rmask != -1)) << 2);
DELTA(hp, ri->ri_stride, uint32_t *);
}
DELTA(rp, ri->ri_stride, uint32_t *);
}
}
}
static void
NAME(copycols)(void *cookie, int row, int src, int dst, int num)
{
struct rasops_info *ri = (struct rasops_info *)cookie;
int height, width, lnum, rnum, sb, db, full, cnt, sboff;
uint32_t lmask, rmask, tmp;
uint32_t *sp, *dp, *srp, *drp, *hp;
bool sbover;
hp = NULL;
if (__predict_false(dst == src))
return;
#ifdef RASOPS_CLIPPING
if ((unsigned)row >= (unsigned)ri->ri_rows)
return;
if (src < 0) {
num += src;
src = 0;
}
if (src + num > ri->ri_cols)
num = ri->ri_cols - src;
if (dst < 0) {
num += dst;
dst = 0;
}
if (dst + num > ri->ri_cols)
num = ri->ri_cols - dst;
if (num <= 0)
return;
#endif
height = ri->ri_font->fontheight;
width = ri->ri_font->fontwidth << PIXEL_SHIFT;
row *= ri->ri_yscale;
src *= width;
dst *= width;
num *= width;
sb = src & 31;
db = dst & 31;
if (db + num <= 32) {
srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
if (ri->ri_hwbits)
hp = (uint32_t *)(ri->ri_hwbits + row +
((dst >> 3) & ~3));
while (height--) {
GETBITS(srp, sb, num, tmp);
PUTBITS(tmp, db, num, drp);
if (ri->ri_hwbits) {
*hp = *drp;
DELTA(hp, ri->ri_stride, uint32_t *);
}
DELTA(srp, ri->ri_stride, uint32_t *);
DELTA(drp, ri->ri_stride, uint32_t *);
}
return;
}
lmask = rasops_rmask[db];
rmask = rasops_lmask[(dst + num) & 31];
lnum = (32 - db) & 31;
rnum = (dst + num) & 31;
if (lmask != 0)
full = (num - lnum) >> 5;
else
full = num >> 5;
if (src < dst && src + num > dst) {
srp = (uint32_t *)(ri->ri_bits + row +
(((src + num) >> 3) & ~3));
drp = (uint32_t *)(ri->ri_bits + row +
(((dst + num) >> 3) & ~3));
if (ri->ri_hwbits) {
hp = (uint32_t *)(ri->ri_hwbits + row +
(((dst + num) >> 3) & ~3));
hp -= (lmask != 0) + full;
}
sboff = (src + num) & 31;
sbover = sb + lnum >= 32;
if ((sboff -= rnum) < 0) {
srp--;
sboff += 32;
}
while (height--) {
sp = srp;
dp = drp;
if (rmask != 0) {
GETBITS(sp, sboff, rnum, tmp);
PUTBITS(tmp, 0, rnum, dp);
}
for (cnt = full; cnt; cnt--) {
--dp;
--sp;
GETBITS(sp, sboff, 32, tmp);
*dp = tmp;
}
if (lmask != 0) {
if (sbover)
--sp;
--dp;
GETBITS(sp, sb, lnum, tmp);
PUTBITS(tmp, db, lnum, dp);
}
if (ri->ri_hwbits) {
memcpy(hp, dp, ((lmask != 0) + full +
(rmask != 0)) << 2);
DELTA(hp, ri->ri_stride, uint32_t *);
}
DELTA(srp, ri->ri_stride, uint32_t *);
DELTA(drp, ri->ri_stride, uint32_t *);
}
} else {
srp = (uint32_t *)(ri->ri_bits + row + ((src >> 3) & ~3));
drp = (uint32_t *)(ri->ri_bits + row + ((dst >> 3) & ~3));
if (ri->ri_hwbits)
hp = (uint32_t *)(ri->ri_hwbits + row +
((dst >> 3) & ~3));
while (height--) {
sp = srp;
dp = drp;
sboff = sb;
if (lmask != 0) {
GETBITS(sp, sboff, lnum, tmp);
PUTBITS(tmp, db, lnum, dp);
dp++;
if ((sboff += lnum) > 31) {
sp++;
sboff -= 32;
}
}
for (cnt = full; cnt; cnt--, sp++) {
GETBITS(sp, sboff, 32, tmp);
*dp++ = tmp;
}
if (rmask != 0) {
GETBITS(sp, sboff, rnum, tmp);
PUTBITS(tmp, 0, rnum, dp);
}
if (ri->ri_hwbits) {
memcpy(hp, drp, ((lmask != 0) + full +
(rmask != 0)) << 2);
DELTA(hp, ri->ri_stride, uint32_t *);
}
DELTA(srp, ri->ri_stride, uint32_t *);
DELTA(drp, ri->ri_stride, uint32_t *);
}
}
}
#undef PIXEL_SHIFT
#undef NAME
#undef NAME1
#undef NAME2
#endif