/*:::::*/ void fb_hPrepareTarget(FB_GFXCTX *context, void *target) { PUT_HEADER *header; unsigned char *data; int i, h; if (target) { if (target != context->last_target) { if (context->last_target == NULL) fb_hMemCpy(context->old_view, context->view, sizeof(int) * 4); header = (PUT_HEADER *)target; context->view_x = 0; context->view_y = 0; if (header->type == PUT_HEADER_NEW) { context->view_w = header->width; context->view_h = h = header->height; context->target_bpp = header->bpp; context->target_pitch = header->pitch; fb_hSetupFuncs(header->bpp); data = (unsigned char *)target + sizeof(PUT_HEADER); } else { context->view_w = header->old.width; context->view_h = h = header->old.height; context->target_bpp = __fb_gfx->bpp; context->target_pitch = context->view_w * __fb_gfx->bpp; data = (unsigned char *)target + 4; } if (h > context->max_h) { context->line = (unsigned char **)realloc(context->line, h * sizeof(unsigned char *)); context->max_h = h; } for (i = 0; i < h; i++) context->line[i] = data + (i * context->target_pitch); context->flags |= CTX_BUFFER_SET; } } else if (context->flags & (CTX_BUFFER_SET | CTX_BUFFER_INIT)) { fb_hMemCpy(context->view, context->old_view, sizeof(int) * 4); context->target_bpp = __fb_gfx->bpp; context->target_pitch = __fb_gfx->pitch; for (i = 0; i < __fb_gfx->h; i++) context->line[i] = __fb_gfx->page[context->work_page] + (i * __fb_gfx->pitch); fb_hSetupFuncs(__fb_gfx->bpp); context->flags &= ~(CTX_BUFFER_SET | CTX_BUFFER_INIT); } context->last_target = target; }
FBCALL int fb_GfxEvent(EVENT *event) { EVENT *e = NULL; FB_GRAPHICS_LOCK( ); if (!__fb_gfx) { FB_GRAPHICS_UNLOCK( ); return FB_FALSE; } EVENT_LOCK(); if (__fb_gfx->event_head != __fb_gfx->event_tail) { e = &__fb_gfx->event_queue[__fb_gfx->event_head]; if (event) __fb_gfx->event_head = (__fb_gfx->event_head + 1) & (MAX_EVENTS - 1); } if (e && event) fb_hMemCpy(event, e, sizeof(EVENT)); EVENT_UNLOCK(); FB_GRAPHICS_UNLOCK( ); return e ? FB_TRUE : FB_FALSE; }
FBCALL void fb_GfxSetWindowTitle(FBSTRING *title) { fb_hMemSet(window_title_buff, 0, WINDOW_TITLE_SIZE); fb_hMemCpy(window_title_buff, title->data, MIN(WINDOW_TITLE_SIZE - 1, FB_STRSIZE(title))); __fb_window_title = window_title_buff; if ((__fb_gfx) && (__fb_gfx->driver->set_window_title)) __fb_gfx->driver->set_window_title(__fb_window_title); /* del if temp */ fb_hStrDelTemp( title ); }
/*:::::*/ void fb_hPostEvent(EVENT *e) { EVENT *slot; EVENT_LOCK(); slot = &__fb_gfx->event_queue[__fb_gfx->event_tail]; fb_hMemCpy(slot, e, sizeof(EVENT)); if (((__fb_gfx->event_tail + 1) & (MAX_EVENTS - 1)) == __fb_gfx->event_head) __fb_gfx->event_head = (__fb_gfx->event_head + 1) & (MAX_EVENTS - 1); __fb_gfx->event_tail = (__fb_gfx->event_tail + 1) & (MAX_EVENTS - 1); EVENT_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 void *fb_hPixelCpy4(void *dest, const void *src, size_t size) { return fb_hMemCpy(dest, src, size << 2); }