/* Ordering of the SPLICE calls here is important to avoid
* a Solaris compiler/cpp whitespace bug
*/
#define src_pixel_t SPLICE(SPLICE(uint, SRC), _t)
#define dst_pixel_t SPLICE(SPLICE(uint, DST), _t)
#define SUFFIX() SPLICE(SRC,SPLICE(x,DST))
#define BLIT SPLICE(gvnc_blt_, SUFFIX())
#define FILL SPLICE(gvnc_fill_, SUFFIX())
#define FAST_FILL SPLICE(gvnc_fill_fast_, SUFFIX())
#define SUBRECT SPLICE(gvnc_hextile_, SUFFIX())
static void FAST_FILL(struct gvnc *gvnc, src_pixel_t *sp,
int x, int y, int width, int height)
{
uint8_t *dst = gvnc_get_local(gvnc, x, y);
int i;
for (i = 0; i < 1; i++) {
int j;
dst_pixel_t *dp = (dst_pixel_t *)dst;
for (j = 0; j < width; j++) {
*dp = *sp;
dp++;
}
dst += gvnc->local.linesize;
}
for (i = 1; i < height; i++) {
memcpy(dst, dst - gvnc->local.linesize, width * sizeof(*sp));
dst += gvnc->local.linesize;
}
}
static void FILL(struct gvnc *gvnc, src_pixel_t *sp,
int x, int y, int width, int height)
{
uint8_t *dst = gvnc_get_local(gvnc, x, y);
int i;
for (i = 0; i < 1; i++) {
dst_pixel_t *dp = (dst_pixel_t *)dst;
int j;
for (j = 0; j < width; j++) {
*dp = ((*sp >> gvnc->rrs) & gvnc->rm) << gvnc->rls
| ((*sp >> gvnc->grs) & gvnc->gm) << gvnc->gls
| ((*sp >> gvnc->brs) & gvnc->bm) << gvnc->bls;
dp++;
}
dst += gvnc->local.linesize;
}
for (i = 1; i < height; i++) {
memcpy(dst, dst - gvnc->local.linesize, width * sizeof(dst_pixel_t));
dst += gvnc->local.linesize;
}
}
static void BLIT(struct gvnc *gvnc, uint8_t *src, int pitch, int x, int y, int w, int h)
{
uint8_t *dst = gvnc_get_local(gvnc, x, y);
int i;
for (i = 0; i < h; i++) {
dst_pixel_t *dp = (dst_pixel_t *)dst;
src_pixel_t *sp = (src_pixel_t *)src;
int j;
for (j = 0; j < w; j++) {
*dp = ((*sp >> gvnc->rrs) & gvnc->rm) << gvnc->rls
| ((*sp >> gvnc->grs) & gvnc->gm) << gvnc->gls
| ((*sp >> gvnc->brs) & gvnc->bm) << gvnc->bls;
dp++;
sp++;
}
dst += gvnc->local.linesize;
src += pitch;
}
}
static void SUBRECT(struct gvnc *gvnc, uint8_t flags, uint16_t x, uint16_t y,
uint16_t width, uint16_t height, src_pixel_t *fg, src_pixel_t *bg)
{
int stride = width * sizeof(src_pixel_t);
int i;
if (flags & 0x01) {
/* Raw tile */
if (gvnc->perfect_match) {
uint8_t *dst = gvnc_get_local(gvnc, x, y);
for (i = 0; i < height; i++) {
gvnc_read(gvnc, dst, stride);
dst += gvnc->local.linesize;
}
} else {
uint8_t data[16 * 16 * sizeof(src_pixel_t)];
gvnc_read(gvnc, data, stride * height);
BLIT(gvnc, data, stride, x, y, width, height);
}
} else {
/* Background Specified */
if (flags & 0x02)
gvnc_read(gvnc, bg, sizeof(*bg));
/* Foreground Specified */
if (flags & 0x04)
gvnc_read(gvnc, fg, sizeof(*fg));
if (gvnc->perfect_match)
FAST_FILL(gvnc, bg, x, y, width, height);
else
FILL(gvnc, bg, x, y, width, height);
/* AnySubrects */
if (flags & 0x08) {
uint8_t n_rects = gvnc_read_u8(gvnc);
for (i = 0; i < n_rects; i++) {
uint8_t xy, wh;
/* SubrectsColored */
if (flags & 0x10)
gvnc_read(gvnc, fg, sizeof(*fg));
xy = gvnc_read_u8(gvnc);
wh = gvnc_read_u8(gvnc);
if (gvnc->perfect_match)
FAST_FILL(gvnc, fg,
x + nibhi(xy), y + niblo(xy),
nibhi(wh) + 1, niblo(wh) + 1);
else
FILL(gvnc, fg,
x + nibhi(xy), y + niblo(xy),
nibhi(wh) + 1, niblo(wh) + 1);
}
}
}
}
#undef SUBRECT
#undef FILL
#undef FAST_FILL
#undef BLIT
#undef dst_pixel_t
#undef src_pixel_t
/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* tab-width: 8
* End:
*/
syntax highlighted by Code2HTML, v. 0.9.1