From 73aad0447c662e066a196c3eac9466036dc81ffa Mon Sep 17 00:00:00 2001 From: Sam Hocevar Date: Wed, 22 Mar 2006 19:54:37 +0000 Subject: [PATCH] * Added the cucul_blit() function. It lets us blit various canvas one onto the other with an optional mask. --- cucul/canvas.c | 45 +++++++++++++++++++++++++++++++++++--- cucul/cucul.h | 12 ++++++----- test/Makefile.am | 2 +- test/gamma.c | 56 ++++++++++++++++++++++++++++++++++++++---------- 4 files changed, 95 insertions(+), 20 deletions(-) diff --git a/cucul/canvas.c b/cucul/canvas.c index 16d7415..cee5408 100644 --- a/cucul/canvas.c +++ b/cucul/canvas.c @@ -65,7 +65,7 @@ void cucul_set_color(cucul_t *qq, enum cucul_color fgcolor, * * \return The current foreground colour. */ -enum cucul_color cucul_get_fg_color(cucul_t *qq) +enum cucul_color cucul_get_fg_color(cucul_t const *qq) { return qq->fgcolor; } @@ -77,7 +77,7 @@ enum cucul_color cucul_get_fg_color(cucul_t *qq) * * \return The current background colour. */ -enum cucul_color cucul_get_bg_color(cucul_t *qq) +enum cucul_color cucul_get_bg_color(cucul_t const *qq) { return qq->bgcolor; } @@ -226,7 +226,7 @@ void cucul_printf(cucul_t *qq, int x, int y, char const *format, ...) * * This function fills a byte array with the character values. */ -void cucul_get_screen(cucul_t *qq, char *buffer) +void cucul_get_screen(cucul_t const *qq, char *buffer) { unsigned int x, y; @@ -259,3 +259,42 @@ void cucul_clear(cucul_t *qq) cucul_set_color(qq, oldfg, oldbg); } +/** \brief Blit a canvas onto another one. + * + * This function blits a canvas onto another one at the given coordinates. + * An optional mask canvas can be used. + * + * \param dst The destination canvas. + * \param x X coordinate. + * \param y Y coordinate. + * \param src The source canvas. + * \param mask The mask canvas. + */ +void cucul_blit(cucul_t *dst, int x, int y, + cucul_t const *src, cucul_t const *mask) +{ + int i, j, starti, startj, endi, endj; + + if(src->width != mask->width || src->height != mask->height) + return; + + starti = x < 0 ? -x : 0; + startj = y < 0 ? -y : 0; + endi = (x + src->width >= dst->width) ? dst->width - x : src->width; + endj = (y + src->height >= dst->height) ? dst->height - y : src->height; + + for(j = startj; j < endj; j++) + { + for(i = starti; i < endi; i++) + { + if(mask && mask->chars[j * src->width + i] == (uint32_t)' ') + continue; + + dst->chars[(j + y) * dst->width + (i + x)] + = src->chars[j * src->width + i]; + dst->attr[(j + y) * dst->width + (i + x)] + = src->attr[j * src->width + i]; + } + } +} + diff --git a/cucul/cucul.h b/cucul/cucul.h index 21eb660..0571574 100644 --- a/cucul/cucul.h +++ b/cucul/cucul.h @@ -128,20 +128,22 @@ char const *cucul_get_feature_name(enum cucul_feature); void cucul_end(cucul_t *); /* @} */ -/** \defgroup char Character printing +/** \defgroup canvas Canvas drawing * - * These functions provide low-level character printing routines. + * These functions provide low-level character printing routines and + * higher level graphics functions. * * @{ */ void cucul_set_color(cucul_t *, enum cucul_color, enum cucul_color); -enum cucul_color cucul_get_fg_color(cucul_t *); -enum cucul_color cucul_get_bg_color(cucul_t *); +enum cucul_color cucul_get_fg_color(cucul_t const *); +enum cucul_color cucul_get_bg_color(cucul_t const *); char const *cucul_get_color_name(enum cucul_color); void cucul_putchar(cucul_t *, int, int, char); void cucul_putstr(cucul_t *, int, int, char const *); void cucul_printf(cucul_t *, int, int, char const *, ...); -void cucul_get_screen(cucul_t *, char *); +void cucul_get_screen(cucul_t const *, char *); void cucul_clear(cucul_t *); +void cucul_blit(cucul_t *, int, int, cucul_t const *, cucul_t const *); /* @} */ /** \defgroup prim Primitives drawing diff --git a/test/Makefile.am b/test/Makefile.am index cd57198..bdc844b 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -23,7 +23,7 @@ export_LDADD = ../cucul/libcucul.la @CUCUL_LIBS@ export_CPPFLAGS = -I$(top_srcdir)/cucul gamma_SOURCES = gamma.c -gamma_LDADD = ../caca/libcaca.la ../cucul/libcucul.la @CACA_LIBS@ +gamma_LDADD = ../caca/libcaca.la ../cucul/libcucul.la @CACA_LIBS@ @MATH_LIBS@ gamma_CPPFLAGS = -I$(top_srcdir)/cucul -I$(top_srcdir)/caca hsv_SOURCES = hsv.c diff --git a/test/gamma.c b/test/gamma.c index c6b1334..c83313e 100644 --- a/test/gamma.c +++ b/test/gamma.c @@ -21,6 +21,11 @@ typedef unsigned short uint16_t; typedef unsigned int uint32_t; #endif +#if !defined(__KERNEL__) +# include +# include +#endif + #include "cucul.h" #include "caca.h" @@ -28,15 +33,18 @@ uint32_t buffer[256 * 4]; int main(void) { - cucul_t *qq; + cucul_t *qq, *gg, *mask; caca_t *kk; - struct cucul_bitmap *left, *right; + float gam = 1.0; int x; qq = cucul_init(0, 0); kk = caca_attach(qq); + gg = cucul_init(cucul_get_width(qq), cucul_get_height(qq)); + mask = cucul_init(cucul_get_width(qq), cucul_get_height(qq)); + for(x = 0; x < 256; x++) { buffer[x] = (x << 16) | (x << 8) | (x<< 0); @@ -51,24 +59,50 @@ int main(void) 0x00ff0000, 0x0000ff00, 0x000000ff, 0x0); caca_set_delay(kk, 20000); - for(x = 0; ; x = (x + 1) % 256) + for(x = 0; ; x++) { - float g = (x > 128) ? (256.0 + 8.0 - x) / 64.0 : (8.0 + x) / 64.0; - - if(caca_get_event(kk, CACA_EVENT_KEY_PRESS)) + int ev = caca_get_event(kk, CACA_EVENT_KEY_PRESS); + + if(ev == (CACA_EVENT_KEY_PRESS | CACA_KEY_LEFT)) + gam /= 1.03; + else if(ev == (CACA_EVENT_KEY_PRESS | CACA_KEY_RIGHT)) + gam *= 1.03; + else if(ev == (CACA_EVENT_KEY_PRESS | CACA_KEY_DOWN)) + gam = 1.0; + else if(ev == (CACA_EVENT_KEY_PRESS | CACA_KEY_ESCAPE)) break; - cucul_draw_bitmap(qq, 0, cucul_get_height(qq) / 2, + /* Resize the spare canvas, just in case the main one changed */ + cucul_set_size(gg, cucul_get_width(qq), cucul_get_height(qq)); + cucul_set_size(mask, cucul_get_width(qq), cucul_get_height(qq)); + + /* Draw the regular bitmap on the main canvas */ + cucul_draw_bitmap(qq, 0, 0, cucul_get_width(qq) - 1, cucul_get_height(qq) - 1, left, buffer); - cucul_set_bitmap_gamma(right, g); - cucul_draw_bitmap(qq, 0, 0, - cucul_get_width(qq) - 1, cucul_get_height(qq) / 2 - 1, + /* Draw the gamma-modified bitmap on the spare canvas */ + cucul_set_bitmap_gamma(right, gam); + cucul_draw_bitmap(gg, 0, 0, + cucul_get_width(gg) - 1, cucul_get_height(gg) - 1, right, buffer); + /* Draw something on the mask */ + cucul_clear(mask); + cucul_set_color(mask, CUCUL_COLOR_WHITE, CUCUL_COLOR_WHITE); + cucul_fill_ellipse(mask, (1.0 + sin(0.05 * (float)x)) + * 0.5 * cucul_get_width(mask), + (1.0 + cos(0.05 * (float)x)) + * 0.5 * cucul_get_height(mask), + cucul_get_width(mask) / 2, + cucul_get_height(mask) / 2, '#'); + + /* Blit the spare canvas onto the first one */ + cucul_blit(qq, 0, 0, gg, mask); + cucul_set_color(qq, CUCUL_COLOR_WHITE, CUCUL_COLOR_BLUE); - cucul_printf(qq, 2, 1, "gamma=%g", g); + cucul_printf(qq, 2, 1, + "gamma=%g - use arrows to change, Esc to quit", gam); caca_display(kk); }