/* Default fallback */ static inline void fallback(ggi_visual *src, int sx, int sy, int w, int h, ggi_visual *dst, int dx, int dy) { ggi_pixel cur_src; ggi_pixel cur_dst = 0; uint8_t *dstptr; int stride; DPRINT_DRAW("linear-8: fallback to slow crossblit.\n"); LIBGGIGetPixel(src, sx, sy, &cur_src); cur_src++; /* assure safe init */ stride = LIBGGI_FB_W_STRIDE(dst); dstptr = (uint8_t*) LIBGGI_CURWRITE(dst) + dy*stride + dx; for (; h > 0; h--, sy++, dy++) { int x; for (x=0; x < w; x++) { ggi_pixel pixel; LIBGGIGetPixel(src, sx+x, sy, &pixel); if (pixel != cur_src) { ggi_color col; LIBGGIUnmapPixel(src, pixel, &col); cur_dst = LIBGGIMapColor(dst, &col); cur_src = pixel; } *(dstptr+x) = cur_dst; } dstptr += stride; } }
int GGI_lin8_copybox(ggi_visual *vis, int x, int y, int w, int h, int nx, int ny) { uint8_t *src, *dest; int stride = LIBGGI_FB_W_STRIDE(vis); int line; LIBGGICLIP_COPYBOX(vis, x, y, w, h, nx, ny); PREPARE_FB(vis); if (ny < y) { src = (uint8_t *)LIBGGI_CURREAD(vis) + y*stride + x; dest = (uint8_t *)LIBGGI_CURWRITE(vis) + ny*stride + nx; for (line=0; line < h; line++, src += stride, dest += stride) { memmove(dest, src, (size_t)(w)); } } else { src = (uint8_t *)LIBGGI_CURREAD(vis) + (y+h-1)*stride + x; dest = (uint8_t *)LIBGGI_CURWRITE(vis) + (ny+h-1)*stride + nx; for (line=0; line < h; line++, src -= stride, dest -= stride) { memmove(dest, src, (size_t)(w)); } } return 0; }
static inline void do_drawhline(struct ggi_visual *vis, int x, int y, int w) { uint8_t *fb; uint8_t fg; fb = (uint8_t *) LIBGGI_CURWRITE(vis)+y*LIBGGI_FB_W_STRIDE(vis)+(x/2); fg = (uint8_t) LIBGGI_GC_FGCOLOR(vis) | (LIBGGI_GC_FGCOLOR(vis)<<4); PREPARE_FB(vis); /* x is odd. Read-modify-write right pixel. */ if (x & 0x01) { *fb = (*fb & 0x0f) | (fg & 0xf0); fb++; w--; } memset(fb, fg, (size_t)(w/2)); /* Dangling right pixel. */ if (w & 0x01) { fb += w/2; *fb = (*fb & 0xf0) | (fg & 0x0f); } }
static inline void do_drawhline(ggi_visual *vis, int x, int y, int w) { int i, w32; uint32_t *fb32; uint16_t *fb16; uint32_t val = LIBGGI_GC_FGCOLOR(vis) | (LIBGGI_GC_FGCOLOR(vis) << 16); PREPARE_FB(vis); fb16 = (uint16_t*)((uint8_t*)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis) + x*2); if (x%2) { *(fb16++) = val; w--; } w32 = w/2; fb32 = (uint32_t*) fb16; for (i = 0; i < w32; i++) { *(fb32++) = val; } if (w%2) { fb16 = (uint16_t *) fb32; *fb16 = val; } }
int GGI_lin16_putbox(struct ggi_visual *vis, int x, int y, int w, int h, const void *buffer) { const uint16_t *src = buffer; uint8_t *dest; int srcwidth = w; int destwidth = LIBGGI_FB_W_STRIDE(vis); LIBGGICLIP_PUTBOX(vis,x,y,w,h,src,srcwidth, *1); PREPARE_FB(vis); dest = (uint8_t *)LIBGGI_CURWRITE(vis) + (y*destwidth + x*2); /* Width should be in bytes */ w *= 2; /* Optimized full-width case */ if (w == destwidth && x == 0) { memcpy(dest, src, (size_t)(w*h)); return 0; } while (h > 0) { memcpy(dest, src, (size_t)(w)); dest += destwidth; src += srcwidth; h--; } return 0; }
int GGI_lin32_putpixel_nc(ggi_visual *vis,int x,int y,ggi_pixel col) { *((uint32_t *) ((uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis)+x*sizeof(uint32_t))) = col; return 0; }
int GGI_lin32_drawpixel_nc(ggi_visual *vis,int x,int y) { *((uint32_t *) ((uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis)+x*sizeof(uint32_t))) = LIBGGI_GC_FGCOLOR(vis); return 0; }
int GGIputpixel_nc(struct ggi_visual *vis,int x, int y, ggi_pixel color) { /* Supports only 8, 16, 32 bit modes -- impossible to pixel nonaligned */ memcpy(BANKFB + ((y * LIBGGI_FB_W_STRIDE(vis) + x) << LOGBYTPP), &color, (1 << LOGBYTPP)); return 0; }
int GGIdrawpixel_nc(struct ggi_visual *vis,int x,int y) { /* Supports only 8, 16, 32 bit modes -- impossible to pixel nonaligned */ memcpy(BANKFB + ((y * LIBGGI_FB_W_STRIDE(vis) + x) << LOGBYTPP), &LIBGGI_GC_FGCOLOR(vis), (1 << LOGBYTPP)); return 0; }
int GGI_lin32_putpixela(struct ggi_visual *vis,int x,int y,ggi_pixel col) { CHECKXY(vis,x,y); PREPARE_FB(vis); *((uint32_t *) ((uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis)+x*sizeof(uint32_t))) = col; return 0; }
int GGI_lin32_drawpixela(struct ggi_visual *vis,int x,int y) { CHECKXY(vis,x,y); PREPARE_FB(vis); *((uint32_t *) ((uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis)+x*sizeof(uint32_t))) = LIBGGI_GC_FGCOLOR(vis); return 0; }
/* 8 bit to 8 bit crossblitting. */ static inline void crossblit_8_to_8(ggi_visual *src, int sx, int sy, int w, int h, ggi_visual *dst, int dx, int dy) { uint8_t *srcp, *dstp; int srcstride = LIBGGI_FB_R_STRIDE(src); int dststride = LIBGGI_FB_W_STRIDE(dst); uint8_t conv_tab[256]; DPRINT_DRAW("linear-8: crossblit_8_to_8.\n"); /* Creates the conversion table. A bit simplistic approach, perhaps? */ do { unsigned int i; for (i = 0; i < 256; i++) { ggi_color col; LIBGGIUnmapPixel(src, i, &col); conv_tab[i] = LIBGGIMapColor(dst, &col); } } while (0); srcp = (uint8_t*)LIBGGI_CURREAD(src) + srcstride*sy + sx; dstp = (uint8_t*)LIBGGI_CURWRITE(dst) + dststride*dy + dx*2; srcstride -= w; dststride -= w; for (; h > 0; h--) { int i = (w + 7) / 8; /* We don't believe in the optimizing capabilities of the * compiler hence unroll manually. */ switch (w & 0x7) { default: for (; i > 0; i--) { case 0x0: *dstp++ = conv_tab[*srcp++]; case 0x7: *dstp++ = conv_tab[*srcp++]; case 0x6: *dstp++ = conv_tab[*srcp++]; case 0x5: *dstp++ = conv_tab[*srcp++]; case 0x4: *dstp++ = conv_tab[*srcp++]; case 0x3: *dstp++ = conv_tab[*srcp++]; case 0x2: *dstp++ = conv_tab[*srcp++]; case 0x1: *dstp++ = conv_tab[*srcp++]; } } srcp += srcstride; dstp += dststride; } }
int GGIdrawpixel(struct ggi_visual *vis,int x,int y) { /* This already clips right */ CHECKXY(vis,x,y); /* Supports only 8, 16, 32 bit modes -- impossible to pixel nonaligned */ memcpy(BANKFB + ((y * LIBGGI_FB_W_STRIDE(vis) + x) << LOGBYTPP), &LIBGGI_GC_FGCOLOR(vis), (1 << LOGBYTPP)); return 0; }
int GGIgetpixel_nc(struct ggi_visual *vis,int x,int y,ggi_pixel *pixel) { /* Supports only 8, 16, 32 bit modes -- impossible to pixel nonaligned */ *pixel = 0; memcpy(pixel, RBANKFB + ((y * LIBGGI_FB_W_STRIDE(vis) + x) << LOGBYTPP), (1 << LOGBYTPP)); return 0; }
int GGI_lin16_puthline(ggi_visual *vis, int x, int y, int w, const void *buffer) { const uint16_t *buf16 = buffer; uint8_t *mem; LIBGGICLIP_XYW_BUFMOD(vis, x, y, w, buf16, *1); PREPARE_FB(vis); mem = (uint8_t *)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis) + x*2; memcpy(mem, buf16, (size_t)(w*2)); return 0; }
int GGI_lin16_drawbox(struct ggi_visual *vis, int x, int y, int origw, int h) { uint32_t *buf32; uint16_t *buf16; uint32_t val; int linediff, oddx; LIBGGICLIP_XYWH(vis, x, y, origw, h); PREPARE_FB(vis); val = LIBGGI_GC_FGCOLOR(vis) | (LIBGGI_GC_FGCOLOR(vis) << 16); buf16 = (uint16_t*)((uint8_t*)LIBGGI_CURWRITE(vis) + y*LIBGGI_FB_W_STRIDE(vis) + x*2); linediff = LIBGGI_FB_W_STRIDE(vis) - origw*2; if (x%2) oddx = 1; else oddx = 0; while (h--) { int w = origw; if (oddx) { *(buf16++) = val; w--; } buf32 = (uint32_t*) buf16; while (w > 1) { *(buf32++) = val; w -= 2; } buf16 = (uint16_t*) buf32; if (w) { *(buf16++) = val; } buf16 = (uint16_t*) ((uint8_t*)buf16 + linediff); } return 0; }
/* Blitting between identical visuals */ static inline void crossblit_same(ggi_visual *src, int sx, int sy, int w, int h, ggi_visual *dst, int dx, int dy) { uint8_t *srcp, *dstp; int srcstride = LIBGGI_FB_R_STRIDE(src); int dststride = LIBGGI_FB_W_STRIDE(dst); DPRINT_DRAW("linear-8: DB-accelerating crossblit.\n"); srcp = (uint8_t*)LIBGGI_CURREAD(src) + srcstride*sy + sx; dstp = (uint8_t*)LIBGGI_CURWRITE(dst) + dststride*dy + dx; for (; h != 0; h--) { memcpy(dstp, srcp, (size_t)(w)); srcp += srcstride; dstp += dststride; } }
int GGI_lin8_putc(struct ggi_visual *vis, int x, int y, char c) { #define char_width 8 #define char_height 8 int offset, x_run, y_run; uint8_t *bitmap; bitmap = (uint8_t *)(font) + ( c * char_height ); x_run = char_width; y_run = char_height; offset = 0; { int delta; delta = LIBGGI_GC(vis)->cliptl.x - x; if ( delta > 0 ) { if ( delta >= x_run ) { return 0; } else { x_run -= delta; offset += delta; x += delta; } } delta = ( x + x_run ) - LIBGGI_GC(vis)->clipbr.x; if ( delta > 0 ) { if ( delta >= x_run ) { return 0; } else { x_run -= delta; } } delta = LIBGGI_GC(vis)->cliptl.y - y; if ( delta > 0 ) { if ( delta >= y_run ) { return 0; } else { y_run -= delta; bitmap += delta; y += delta; } } delta = ( y + y_run ) - LIBGGI_GC(vis)->clipbr.y; if ( delta > 0 ) { if ( delta >= y_run ) { return 0; } else { y_run -= delta; } } } { int y_iter; register uint8_t *fb; int add_stride; PREPARE_FB(vis); add_stride = LIBGGI_FB_W_STRIDE(vis); fb = (uint8_t *)LIBGGI_CURWRITE(vis) + ( y * add_stride ) + x; add_stride -= x_run; y_run += y; x_run += x; for ( y_iter = y ; y_iter < y_run ; y_iter++, bitmap++, fb += add_stride ) { register int x_iter; register uint8_t row; row = *bitmap << offset; for ( x_iter = x ; x_iter < x_run ; x_iter++, row <<= 1, fb++ ) { *fb = ( row & 128 ) ? (uint8_t)LIBGGI_GC_FGCOLOR(vis) : (uint8_t)LIBGGI_GC_BGCOLOR(vis); } } } return 0; #undef char_width #undef char_height }