Changeset bea947f in mainline


Ignore:
Timestamp:
2020-05-24T17:59:02Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b3b00b6
Parents:
ef20a91
Message:

Implement bitmap color key to allow transparent cursor background

This seems to be the simplest solution of them all. It will work
on any bit depth except 1 bit per pixel (monochrome), where we would
need to extend the bitmap with a bit mask instead.

Location:
uspace
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/gfxdemo/gfxdemo.c

    ref20a91 rbea947f  
    215215}
    216216
     217/** Render circle to a bitmap.
     218 *
     219 * @param bitmap Bitmap
     220 * @param w Bitmap width
     221 * @param h Bitmap height
     222 * @return EOK on success or an error code
     223 */
     224static errno_t bitmap_circle(gfx_bitmap_t *bitmap, gfx_coord_t w, gfx_coord_t h)
     225{
     226        int i, j;
     227        int k;
     228        pixelmap_t pixelmap;
     229        gfx_bitmap_alloc_t alloc;
     230        errno_t rc;
     231
     232        rc = gfx_bitmap_get_alloc(bitmap, &alloc);
     233        if (rc != EOK)
     234                return rc;
     235
     236        /* In absence of anything else, use pixelmap */
     237        pixelmap.width = w;
     238        pixelmap.height = h;
     239        pixelmap.data = alloc.pixels;
     240
     241        for (i = 0; i < w; i++) {
     242                for (j = 0; j < h; j++) {
     243                        k = i * i + j * j;
     244                        pixelmap_put_pixel(&pixelmap, i, j,
     245                            k < w * w / 2 ? PIXEL(255, 0, 255, 0) :
     246                            PIXEL(0, 255, 0, 255));
     247                }
     248        }
     249
     250        return EOK;
     251}
     252
    217253/** Run bitmap demo on a graphic context.
    218254 *
     
    329365        return rc;
    330366}
    331 
    332 /** Run demo loop on a graphic context.
     367/** Run bitmap color key demo on a graphic context.
    333368 *
    334369 * @param gc Graphic context
     
    336371 * @param h Height
    337372 */
     373static errno_t demo_bitmap_kc(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
     374{
     375        gfx_bitmap_t *bitmap;
     376        gfx_bitmap_params_t params;
     377        int i, j;
     378        gfx_coord2_t offs;
     379        errno_t rc;
     380
     381        rc = clear_scr(gc, w, h);
     382        if (rc != EOK)
     383                return rc;
     384
     385        params.rect.p0.x = 0;
     386        params.rect.p0.y = 0;
     387        params.rect.p1.x = 40;
     388        params.rect.p1.y = 40;
     389        params.flags = bmpf_color_key;
     390        params.key_color = PIXEL(0, 255, 0, 255);
     391
     392        rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
     393        if (rc != EOK)
     394                return rc;
     395
     396        rc = bitmap_circle(bitmap, 40, 40);
     397        if (rc != EOK)
     398                goto error;
     399
     400        for (j = 0; j < 10; j++) {
     401                for (i = 0; i < 10; i++) {
     402                        offs.x = j * 20 + i * 20;
     403                        offs.y = i * 20;
     404
     405                        rc = gfx_bitmap_render(bitmap, NULL, &offs);
     406                        if (rc != EOK)
     407                                goto error;
     408                }
     409
     410                fibril_usleep(500 * 1000);
     411
     412                if (quit)
     413                        break;
     414        }
     415
     416        gfx_bitmap_destroy(bitmap);
     417
     418        return EOK;
     419error:
     420        gfx_bitmap_destroy(bitmap);
     421        return rc;
     422}
     423
     424/** Run demo loop on a graphic context.
     425 *
     426 * @param gc Graphic context
     427 * @param w Width
     428 * @param h Height
     429 */
    338430static errno_t demo_loop(gfx_context_t *gc, gfx_coord_t w, gfx_coord_t h)
    339431{
     
    350442
    351443                rc = demo_bitmap2(gc, w, h);
     444                if (rc != EOK)
     445                        return rc;
     446
     447                rc = demo_bitmap_kc(gc, w, h);
    352448                if (rc != EOK)
    353449                        return rc;
  • uspace/drv/fb/kfb/port.c

    ref20a91 rbea947f  
    9090        gfx_bitmap_alloc_t alloc;
    9191        gfx_rect_t rect;
     92        gfx_bitmap_flags_t flags;
     93        pixel_t key_color;
    9294        bool myalloc;
    9395} kfb_bitmap_t;
     
    203205        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
    204206        kfbbm->rect = params->rect;
     207        kfbbm->flags = params->flags;
     208        kfbbm->key_color = params->key_color;
    205209
    206210        if (alloc == NULL) {
     
    298302        gfx_rect_clip(&srect, &skfbrect, &crect);
    299303
    300         for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
    301                 for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
    302                         gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
    303                         gfx_coord2_add(&pos, &offs, &dp);
    304 
    305                         color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
    306                         kfb->pixel2visual(kfb->addr +
    307                             FB_POS(kfb, dp.x, dp.y), color);
     304        if ((kfbbm->flags & bmpf_color_key) != 0) {
     305                for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
     306                        for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
     307                                gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
     308                                gfx_coord2_add(&pos, &offs, &dp);
     309
     310                                color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
     311                                if (color != kfbbm->key_color) {
     312                                        kfb->pixel2visual(kfb->addr +
     313                                            FB_POS(kfb, dp.x, dp.y), color);
     314                                }
     315                        }
     316                }
     317        } else {
     318                for (pos.y = crect.p0.y; pos.y < crect.p1.y; pos.y++) {
     319                        for (pos.x = crect.p0.x; pos.x < crect.p1.x; pos.x++) {
     320                                gfx_coord2_subtract(&pos, &kfbbm->rect.p0, &sp);
     321                                gfx_coord2_add(&pos, &offs, &dp);
     322
     323                                color = pixelmap_get_pixel(&pbm, sp.x, sp.y);
     324                                kfb->pixel2visual(kfb->addr +
     325                                    FB_POS(kfb, dp.x, dp.y), color);
     326                        }
    308327                }
    309328        }
  • uspace/lib/congfx/private/console.h

    ref20a91 rbea947f  
    5252        /** Console control structure */
    5353        console_ctrl_t *con;
     54        /** Console bounding rectangle */
     55        gfx_rect_t rect;
    5456        /** File for printing characters */
    5557        FILE *fout;
     
    6870        /** Rectangle covered by bitmap */
    6971        gfx_rect_t rect;
     72        /** Bitmap flags */
     73        gfx_bitmap_flags_t flags;
     74        /** Key color */
     75        pixel_t key_color;
    7076} console_gc_bitmap_t;
    7177
  • uspace/lib/congfx/src/console.c

    ref20a91 rbea947f  
    129129        console_gc_t *cgc = NULL;
    130130        gfx_context_t *gc = NULL;
     131        sysarg_t rows;
     132        sysarg_t cols;
    131133        errno_t rc;
    132134
     
    137139        }
    138140
     141        rc = console_get_size(con, &cols, &rows);
     142        if (rc != EOK)
     143                goto error;
     144
    139145        rc = gfx_context_new(&console_gc_ops, cgc, &gc);
    140146        if (rc != EOK)
     
    144150        cgc->con = con;
    145151        cgc->fout = fout;
     152        cgc->rect.p0.x = 0;
     153        cgc->rect.p0.y = 0;
     154        cgc->rect.p1.x = cols;
     155        cgc->rect.p1.y = rows - 1; /* make sure we avoid bottom-right corner */
     156
    146157        *rgc = cgc;
    147158        return EOK;
     
    201212        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
    202213        cbm->rect = params->rect;
     214        cbm->flags = params->flags;
     215        cbm->key_color = params->key_color;
    203216
    204217        if (alloc == NULL) {
     
    256269        gfx_rect_t srect;
    257270        gfx_rect_t drect;
     271        gfx_rect_t crect;
    258272        gfx_coord2_t offs;
    259273
     
    270284        }
    271285
    272         // XXX Add function to translate rectangle
    273286        gfx_rect_translate(&offs, &srect, &drect);
     287        gfx_rect_clip(&drect, &cbm->cgc->rect, &crect);
    274288
    275289        pixelmap.width = cbm->rect.p1.x - cbm->rect.p0.x;
     
    277291        pixelmap.data = cbm->alloc.pixels;
    278292
    279         for (y = drect.p0.y; y < drect.p1.y; y++) {
    280                 console_set_pos(cbm->cgc->con, drect.p0.x, y);
    281 
    282                 for (x = drect.p0.x; x < drect.p1.x; x++) {
    283                         clr = pixelmap_get_pixel(&pixelmap,
    284                             x - offs.x - cbm->rect.p0.x,
    285                             y - offs.y - cbm->rect.p0.y);
    286                         console_set_rgb_color(cbm->cgc->con, clr, clr);
    287 
    288                         rv = fputc('X', cbm->cgc->fout);
    289                         if (rv < 0)
    290                                 return EIO;
    291 
    292                         console_flush(cbm->cgc->con);
     293        if ((cbm->flags & bmpf_color_key) == 0) {
     294                for (y = crect.p0.y; y < crect.p1.y; y++) {
     295                        console_set_pos(cbm->cgc->con, crect.p0.x, y);
     296
     297                        for (x = crect.p0.x; x < crect.p1.x; x++) {
     298                                clr = pixelmap_get_pixel(&pixelmap,
     299                                    x - offs.x - cbm->rect.p0.x,
     300                                    y - offs.y - cbm->rect.p0.y);
     301                                console_set_rgb_color(cbm->cgc->con, clr, clr);
     302
     303                                rv = fputc('X', cbm->cgc->fout);
     304                                if (rv < 0)
     305                                        return EIO;
     306
     307                                console_flush(cbm->cgc->con);
     308                        }
     309                }
     310        } else {
     311                for (y = crect.p0.y; y < crect.p1.y; y++) {
     312                        for (x = crect.p0.x; x < crect.p1.x; x++) {
     313
     314                                clr = pixelmap_get_pixel(&pixelmap,
     315                                    x - offs.x - cbm->rect.p0.x,
     316                                    y - offs.y - cbm->rect.p0.y);
     317                                console_set_rgb_color(cbm->cgc->con, clr, clr);
     318
     319                                if (clr != cbm->key_color) {
     320                                        console_set_pos(cbm->cgc->con, x, y);
     321                                        rv = fputc('X', cbm->cgc->fout);
     322                                        if (rv < 0)
     323                                                return EIO;
     324
     325                                        console_flush(cbm->cgc->con);
     326                                }
     327
     328                        }
    293329                }
    294330        }
  • uspace/lib/gfx/include/types/gfx/bitmap.h

    ref20a91 rbea947f  
    3838
    3939#include <errno.h>
     40#include <io/pixel.h>
    4041#include <stddef.h>
    4142#include <types/gfx/coord.h>
     
    4445typedef struct gfx_bitmap gfx_bitmap_t;
    4546
     47/** Bitmap flags */
     48typedef enum {
     49        /** Enable color key */
     50        bmpf_color_key = 0x1
     51} gfx_bitmap_flags_t;
     52
    4653/** Bitmap parameters */
    4754typedef struct {
    4855        /** Rectangle represented in pixel array */
    4956        gfx_rect_t rect;
     57        /** Bitmap flags */
     58        gfx_bitmap_flags_t flags;
     59        /** Key color */
     60        pixel_t key_color;
    5061} gfx_bitmap_params_t;
    5162
  • uspace/lib/guigfx/private/canvas.h

    ref20a91 rbea947f  
    7272        /** Rectangle covered by bitmap */
    7373        gfx_rect_t rect;
     74        /** Bitmap flags */
     75        gfx_bitmap_flags_t flags;
     76        /** Key color */
     77        pixel_t key_color;
    7478} canvas_gc_bitmap_t;
    7579
  • uspace/lib/guigfx/src/canvas.c

    ref20a91 rbea947f  
    197197        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
    198198        cbm->rect = params->rect;
     199        cbm->flags = params->flags;
     200        cbm->key_color = params->key_color;
    199201
    200202        if (alloc == NULL) {
     
    259261        gfx_coord2_t offs;
    260262        gfx_coord2_t dim;
     263        gfx_coord_t x, y;
     264        pixel_t pixel;
    261265
    262266        if (srect0 != NULL)
     
    288292            PIXELMAP_EXTEND_TRANSPARENT_BLACK);
    289293
    290         drawctx_t drawctx;
    291         drawctx_init(&drawctx, cbm->cgc->surface);
    292 
    293         drawctx_set_source(&drawctx, &source);
    294         drawctx_transfer(&drawctx, drect.p0.x, drect.p0.y, dim.x, dim.y);
     294        if ((cbm->flags & bmpf_color_key) == 0) {
     295                drawctx_t drawctx;
     296                drawctx_init(&drawctx, cbm->cgc->surface);
     297
     298                drawctx_set_source(&drawctx, &source);
     299                drawctx_transfer(&drawctx, drect.p0.x, drect.p0.y, dim.x, dim.y);
     300        } else {
     301                for (y = drect.p0.y; y < drect.p1.y; y++) {
     302                        for (x = drect.p0.x; x < drect.p1.x; x++) {
     303                                pixel = source_determine_pixel(&source, x, y);
     304                                if (pixel != cbm->key_color) {
     305                                        surface_put_pixel(cbm->cgc->surface,
     306                                            x, y, pixel);
     307                                }
     308                        }
     309                }
     310        }
    295311
    296312        update_canvas(cbm->cgc->canvas, cbm->cgc->surface);
  • uspace/srv/hid/display/cursor.c

    ref20a91 rbea947f  
    109109        gfx_bitmap_params_init(&bparams);
    110110        bparams.rect = cursor->rect;
     111        bparams.flags = bmpf_color_key;
     112        bparams.key_color = PIXEL(0, 0, 255, 255);
    111113
    112114        if (cursor->bitmap == NULL) {
  • uspace/srv/hid/display/types/display/window.h

    ref20a91 rbea947f  
    4242#include <gfx/context.h>
    4343#include <gfx/coord.h>
     44#include <io/pixel.h>
    4445#include <io/pixelmap.h>
    4546
     
    115116        /** Bounding rectangle */
    116117        gfx_rect_t rect;
     118        /** Bitmap flags */
     119        gfx_bitmap_flags_t flags;
     120        /** Key color */
     121        pixel_t key_color;
    117122} ds_window_bitmap_t;
    118123
  • uspace/srv/hid/display/window.c

    ref20a91 rbea947f  
    131131{
    132132        ds_window_t *wnd = (ds_window_t *) arg;
    133         ds_window_bitmap_t *cbm = NULL;
     133        ds_window_bitmap_t *wbm = NULL;
    134134        errno_t rc;
    135135
    136         cbm = calloc(1, sizeof(ds_window_bitmap_t));
    137         if (cbm == NULL)
     136        wbm = calloc(1, sizeof(ds_window_bitmap_t));
     137        if (wbm == NULL)
    138138                return ENOMEM;
    139139
    140140        rc = gfx_bitmap_create(ds_display_get_gc(wnd->display), params, alloc,
    141             &cbm->bitmap);
     141            &wbm->bitmap);
    142142        if (rc != EOK)
    143143                goto error;
    144144
    145         cbm->wnd = wnd;
    146         cbm->rect = params->rect;
    147         *rbm = (void *)cbm;
     145        wbm->wnd = wnd;
     146        wbm->rect = params->rect;
     147        wbm->flags = params->flags;
     148        wbm->key_color = params->key_color;
     149        *rbm = (void *)wbm;
    148150        return EOK;
    149151error:
    150         if (cbm != NULL)
    151                 free(cbm);
     152        if (wbm != NULL)
     153                free(wbm);
    152154        return rc;
    153155}
     
    160162static errno_t ds_window_bitmap_destroy(void *bm)
    161163{
    162         ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
    163 
    164         gfx_bitmap_destroy(cbm->bitmap);
    165         free(cbm);
     164        ds_window_bitmap_t *wbm = (ds_window_bitmap_t *)bm;
     165
     166        gfx_bitmap_destroy(wbm->bitmap);
     167        free(wbm);
    166168        return EOK;
    167169}
     
    177179    gfx_coord2_t *offs0)
    178180{
    179         ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
     181        ds_window_bitmap_t *wbm = (ds_window_bitmap_t *)bm;
    180182        gfx_coord2_t doffs;
    181183        gfx_coord2_t offs;
     
    192194        if (srect0 != NULL) {
    193195                /* Clip source rectangle to bitmap rectangle */
    194                 gfx_rect_clip(srect0, &cbm->rect, &srect);
     196                gfx_rect_clip(srect0, &wbm->rect, &srect);
    195197        } else {
    196198                /* Source is entire bitmap rectangle */
    197                 srect = cbm->rect;
     199                srect = wbm->rect;
    198200        }
    199201
     
    206208
    207209        /* Transform window rectangle back to bitmap coordinate system */
    208         gfx_rect_rtranslate(&offs, &cbm->wnd->rect, &swrect);
     210        gfx_rect_rtranslate(&offs, &wbm->wnd->rect, &swrect);
    209211
    210212        /* Clip so that transformed rectangle will be inside the window */
     
    212214
    213215        /* Offset for rendering on screen = window pos + offs */
    214         gfx_coord2_add(&cbm->wnd->dpos, &offs, &doffs);
     216        gfx_coord2_add(&wbm->wnd->dpos, &offs, &doffs);
    215217
    216218        /* Resulting rectangle on the screen we are drawing into */
    217219        gfx_rect_translate(&doffs, &crect, &drect);
    218220
    219         rc = gfx_bitmap_get_alloc(cbm->bitmap, &alloc);
     221        rc = gfx_bitmap_get_alloc(wbm->bitmap, &alloc);
    220222        if (rc != EOK)
    221223                return rc;
    222224
    223         pixelmap.width = cbm->rect.p1.x - cbm->rect.p0.x;
    224         pixelmap.height = cbm->rect.p1.y - cbm->rect.p0.y;
     225        pixelmap.width = wbm->rect.p1.x - wbm->rect.p0.x;
     226        pixelmap.height = wbm->rect.p1.y - wbm->rect.p0.y;
    225227        pixelmap.data = alloc.pixels;
    226228
    227229        /* Render a copy to the backbuffer */
    228         for (y = crect.p0.y; y < crect.p1.y; y++) {
    229                 for (x = crect.p0.x; x < crect.p1.x; x++) {
    230                         pixel = pixelmap_get_pixel(&pixelmap,
    231                             x - cbm->rect.p0.x, y - cbm->rect.p0.y);
    232                         pixelmap_put_pixel(&cbm->wnd->pixelmap,
    233                             x + offs.x - cbm->rect.p0.x + cbm->wnd->rect.p0.x,
    234                             y + offs.y - cbm->rect.p0.y + cbm->wnd->rect.p0.y,
    235                             pixel);
     230        if ((wbm->flags & bmpf_color_key) == 0) {
     231                for (y = crect.p0.y; y < crect.p1.y; y++) {
     232                        for (x = crect.p0.x; x < crect.p1.x; x++) {
     233                                pixel = pixelmap_get_pixel(&pixelmap,
     234                                    x - wbm->rect.p0.x, y - wbm->rect.p0.y);
     235                                pixelmap_put_pixel(&wbm->wnd->pixelmap,
     236                                    x + offs.x - wbm->rect.p0.x + wbm->wnd->rect.p0.x,
     237                                    y + offs.y - wbm->rect.p0.y + wbm->wnd->rect.p0.y,
     238                                    pixel);
     239                        }
    236240                }
     241        } else {
     242                for (y = crect.p0.y; y < crect.p1.y; y++) {
     243                        for (x = crect.p0.x; x < crect.p1.x; x++) {
     244                                pixel = pixelmap_get_pixel(&pixelmap,
     245                                    x - wbm->rect.p0.x, y - wbm->rect.p0.y);
     246                                if (pixel != wbm->key_color) {
     247                                        pixelmap_put_pixel(&wbm->wnd->pixelmap,
     248                                            x + offs.x - wbm->rect.p0.x +
     249                                            wbm->wnd->rect.p0.x,
     250                                            y + offs.y - wbm->rect.p0.y +
     251                                            wbm->wnd->rect.p0.y,
     252                                            pixel);
     253                                }
     254                        }
     255                }
    237256        }
    238257
    239258        /* Repaint this area of the display */
    240         return ds_display_paint(cbm->wnd->display, &drect);
     259        return ds_display_paint(wbm->wnd->display, &drect);
    241260}
    242261
     
    249268static errno_t ds_window_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
    250269{
    251         ds_window_bitmap_t *cbm = (ds_window_bitmap_t *)bm;
    252 
    253         return gfx_bitmap_get_alloc(cbm->bitmap, alloc);
     270        ds_window_bitmap_t *wbm = (ds_window_bitmap_t *)bm;
     271
     272        return gfx_bitmap_get_alloc(wbm->bitmap, alloc);
    254273}
    255274
  • uspace/srv/hid/rfb/main.c

    ref20a91 rbea947f  
    7272        gfx_bitmap_alloc_t alloc;
    7373        gfx_rect_t rect;
     74        gfx_bitmap_flags_t flags;
     75        pixel_t key_color;
    7476        bool myalloc;
    7577} rfb_bitmap_t;
     
    199201        gfx_coord2_subtract(&params->rect.p1, &params->rect.p0, &dim);
    200202        rfbbm->rect = params->rect;
     203        rfbbm->flags = params->flags;
     204        rfbbm->key_color = params->key_color;
    201205
    202206        if (alloc == NULL) {
     
    278282        pbm.data = rfbbm->alloc.pixels;
    279283
    280         for (y = srect.p0.y; y < srect.p1.y; y++) {
    281                 for (x = srect.p0.x; x < srect.p1.x; x++) {
    282                         color = pixelmap_get_pixel(&pbm, x, y);
    283                         pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
    284                             x + offs.x, y + offs.y, color);
     284        if ((rfbbm->flags & bmpf_color_key) == 0) {
     285                for (y = srect.p0.y; y < srect.p1.y; y++) {
     286                        for (x = srect.p0.x; x < srect.p1.x; x++) {
     287                                color = pixelmap_get_pixel(&pbm, x, y);
     288                                pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
     289                                    x + offs.x, y + offs.y, color);
     290                        }
     291                }
     292        } else {
     293                for (y = srect.p0.y; y < srect.p1.y; y++) {
     294                        for (x = srect.p0.x; x < srect.p1.x; x++) {
     295                                color = pixelmap_get_pixel(&pbm, x, y);
     296                                if (color != rfbbm->key_color) {
     297                                        pixelmap_put_pixel(&rfbbm->rfb->rfb.framebuffer,
     298                                            x + offs.x, y + offs.y, color);
     299                                }
     300                        }
    285301                }
    286302        }
Note: See TracChangeset for help on using the changeset viewer.