FBCALL void fb_GfxPset(void *target, float fx, float fy, unsigned int color, int flags, int ispreset) { FB_GFXCTX *context; int x, y; FB_GRAPHICS_LOCK( ); if (!__fb_gfx) { FB_GRAPHICS_UNLOCK( ); return; } context = fb_hGetContext( ); fb_hPrepareTarget(context, target); if (flags & DEFAULT_COLOR_1) { if (ispreset) color = context->bg_color; else color = context->fg_color; } else { color = fb_hFixColor(context->target_bpp, color); } fb_hSetPixelTransfer(context, color); fb_hFixRelative(context, flags, &fx, &fy, NULL, NULL); fb_hTranslateCoord(context, fx, fy, &x, &y); if ((x < context->view_x) || (y < context->view_y) || (x >= context->view_x + context->view_w) || (y >= context->view_y + context->view_h)) { FB_GRAPHICS_UNLOCK( ); return; } DRIVER_LOCK(); context->put_pixel(context, x, y, color); if (__fb_gfx->framebuffer == context->line[0]) __fb_gfx->dirty[y] = TRUE; DRIVER_UNLOCK(); FB_GRAPHICS_UNLOCK( ); }
FBCALL void fb_GfxEllipse(void *target, float fx, float fy, float radius, unsigned int color, float aspect, float start, float end, int fill, int flags) { FB_GFXCTX *context; int x, y, x1, y1, top, bottom; unsigned int orig_color; float a, b, orig_x, orig_y, increment; FB_GRAPHICS_LOCK( ); if (!__fb_gfx || radius <= 0.0) { FB_GRAPHICS_UNLOCK( ); return; } context = fb_hGetContext(); orig_x = fx; orig_y = fy; fb_hPrepareTarget(context, target); orig_color = color; if (flags & DEFAULT_COLOR_1) color = context->fg_color; else color = fb_hFixColor(context->target_bpp, color); fb_hSetPixelTransfer(context, color); fb_hFixRelative(context, flags, &fx, &fy, NULL, NULL); fb_hTranslateCoord(context, fx, fy, &x, &y); if (context->flags & CTX_WINDOW_ACTIVE) { /* radius gets multiplied by the VIEW/WINDOW width ratio (aspect is unchanged) */ radius *= (context->view_w / context->win_w); } if (aspect == 0.0) aspect = __fb_gfx->aspect; if (aspect > 1.0) { a = (radius / aspect); b = radius; } else { a = radius; b = (radius * aspect); } if ((start != 0.0) || (end != 3.141593f * 2.0)) { if (start < 0) { start = -start; get_arc_point(start, a, b, &x1, &y1); x1 = orig_x + x1; y1 = orig_y - y1; fb_GfxLine(target, orig_x, orig_y, x1, y1, orig_color, LINE_TYPE_LINE, 0xFFFF, COORD_TYPE_AA | (flags & ~COORD_TYPE_MASK)); } if (end < 0) { end = -end; get_arc_point(end, a, b, &x1, &y1); x1 = orig_x + x1; y1 = orig_y - y1; fb_GfxLine(target, orig_x, orig_y, x1, y1, orig_color, LINE_TYPE_LINE, 0xFFFF, COORD_TYPE_AA | (flags & ~COORD_TYPE_MASK)); } while (end < start) end += 2 * PI; while (end - start > 2 * PI) start += 2 * PI; increment = 1 / (sqrt(a) * sqrt(b) * 1.5); DRIVER_LOCK(); top = bottom = y; for (; start < end + (increment / 2); start += increment) { get_arc_point(start, a, b, &x1, &y1); x1 = x + x1; y1 = y - y1; if ((x1 < context->view_x) || (x1 >= context->view_x + context->view_w) || (y1 < context->view_y) || (y1 >= context->view_y + context->view_h)) continue; context->put_pixel(context, x1, y1, color); if (y1 > bottom) bottom = y1; if (y1 < top) top = y1; } } else { DRIVER_LOCK(); draw_ellipse(context, x, y, a, b, color, fill, &top, &bottom); } top = MID(context->view_y, top, context->view_y + context->view_h - 1); bottom = MID(context->view_y, bottom, context->view_y + context->view_h - 1); if( top > bottom ) SWAP( top, bottom ); SET_DIRTY(context, top, bottom - top + 1); DRIVER_UNLOCK(); FB_GRAPHICS_UNLOCK( ); }
/*:::::*/ FBCALL void fb_GfxPaint(void *target, float fx, float fy, unsigned int color, unsigned int border_color, FBSTRING *pattern, int mode, int flags) { FB_GFXCTX *context = fb_hGetContext(); int size, x, y; unsigned char data[256], *dest, *src; SPAN **span, *s, *tail, *head; if (!__fb_gfx) return; fb_hPrepareTarget(context, target); if (flags & DEFAULT_COLOR_1) color = context->fg_color; else color = fb_hFixColor(context->target_bpp, color); if (flags & DEFAULT_COLOR_2) border_color = color; else border_color = fb_hFixColor(context->target_bpp, border_color); fb_hSetPixelTransfer(context,color); fb_hFixRelative(context, flags, &fx, &fy, NULL, NULL); fb_hTranslateCoord(context, fx, fy, &x, &y); fb_hMemSet(data, 0, sizeof(data)); if ((mode == PAINT_TYPE_PATTERN) && (pattern)) { fb_hMemCpy(data, pattern->data, MIN(256, FB_STRSIZE(pattern))); } if (pattern) { /* del if temp */ fb_hStrDelTemp( pattern ); } if ((x < context->view_x) || (x >= context->view_x + context->view_w) || (y < context->view_y) || (y >= context->view_y + context->view_h)) return; if (context->get_pixel(context, x, y) == border_color) return; size = sizeof(SPAN *) * (context->view_y + context->view_h); span = (SPAN **)malloc(size); fb_hMemSet(span, 0, size); tail = head = add_span(context, span, &x, y, border_color); /* Find all spans to paint */ while (tail) { if (tail->y - 1 >= context->view_y) { for (x = tail->x1; x <= tail->x2; x++) { if (context->get_pixel(context, x, tail->y - 1) != border_color) { s = add_span(context, span, &x, tail->y - 1, border_color); if (s) { head->next = s; head = s; } } } } if (tail->y + 1 < context->view_y + context->view_h) { for (x = tail->x1; x <= tail->x2; x++) { if (context->get_pixel(context, x, tail->y + 1) != border_color) { s = add_span(context, span, &x, tail->y + 1, border_color); if (s) { head->next = s; head = s; } } } } tail = tail->next; } DRIVER_LOCK(); /* Fill spans */ for (y = context->view_y; y < context->view_y + context->view_h; y++) { for (s = tail = span[y]; s; s = s->row_next, free(tail), tail = s) { dest = context->line[s->y] + (s->x1 * context->target_bpp); if (mode == PAINT_TYPE_FILL) context->pixel_set(dest, color, s->x2 - s->x1 + 1); else { src = data + (((s->y & 0x7) << 3) * context->target_bpp); if (s->x1 & 0x7) { if ((s->x1 & ~0x7) == (s->x2 & ~0x7)) size = s->x2 - s->x1 + 1; else size = 8 - (s->x1 & 0x7); fb_hPixelCpy(dest, src + ((s->x1 & 0x7) * context->target_bpp), size); dest += size * context->target_bpp; } s->x2++; for (x = (s->x1 + 7) >> 3; x < (s->x2 & ~0x7) >> 3; x++) { fb_hPixelCpy(dest, src, 8); dest += 8 * context->target_bpp; } if ((s->x2 & 0x7) && ((s->x1 & ~0x7) != (s->x2 & ~0x7))) fb_hPixelCpy(dest, src, s->x2 & 0x7); } if (__fb_gfx->framebuffer == context->line[0]) __fb_gfx->dirty[context->view_y + y] = TRUE; } } free(span); DRIVER_UNLOCK(); }
/*:::::*/ static int gfx_get(void *target, float fx1, float fy1, float fx2, float fy2, unsigned char *dest, int coord_type, FBARRAY *array, int usenewheader ) { FB_GFXCTX *context = fb_hGetContext(); PUT_HEADER *header; int x1, y1, x2, y2, w, h, pitch; if (!__fb_gfx) return fb_ErrorSetNum(FB_RTERROR_ILLEGALFUNCTIONCALL); fb_hPrepareTarget(context, target); fb_hSetPixelTransfer(context, MASK_A_32); fb_hFixRelative(context, coord_type, &fx1, &fy1, &fx2, &fy2); fb_hTranslateCoord(context, fx1, fy1, &x1, &y1); fb_hTranslateCoord(context, fx2, fy2, &x2, &y2); fb_hFixCoordsOrder(&x1, &y1, &x2, &y2); if ((x1 < context->view_x) || (y1 < context->view_y) || (x2 >= context->view_x + context->view_w) || (y2 >= context->view_y + context->view_h)) return fb_ErrorSetNum(FB_RTERROR_ILLEGALFUNCTIONCALL); w = x2 - x1 + 1; h = y2 - y1 + 1; header = (PUT_HEADER *)dest; if (!usenewheader) { /* use old-style header for compatibility */ header->old.bpp = context->target_bpp; header->old.width = w; header->old.height = h; pitch = w * context->target_bpp; dest += 4; } else { /* use new-style header */ header->type = PUT_HEADER_NEW; header->width = w; header->height = h; header->bpp = context->target_bpp; pitch = header->pitch = ((w * context->target_bpp) + 0xF) & ~0xF; dest += sizeof(PUT_HEADER); } if( array != NULL ) { if ((array->size > 0) && ((intptr_t)dest + (pitch * h) > (intptr_t)array->data + array->size)) return fb_ErrorSetNum(FB_RTERROR_ILLEGALFUNCTIONCALL); } DRIVER_LOCK(); for (; y1 <= y2; y1++) { fb_hPixelCpy(dest, context->line[y1] + (x1 * context->target_bpp), w); dest += pitch; } DRIVER_UNLOCK(); return fb_ErrorSetNum( FB_RTERROR_OK ); }