Changeset d2100e2 in mainline


Ignore:
Timestamp:
2020-08-09T18:40:28Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
06b8383
Parents:
5592c56
Message:

Finish glyph bitmap operations and tests

Setting/getting pixel, opening/saving glyph bitmap.

Location:
uspace/lib/gfxfont
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/gfxfont/private/font.h

    r5592c56 rd2100e2  
    3939
    4040#include <adt/list.h>
     41#include <errno.h>
     42#include <types/gfx/bitmap.h>
    4143#include <types/gfx/context.h>
    4244#include <types/gfx/font.h>
     
    4547 *
    4648 * This is private to libgfxfont.
     49 *
     50 * Font bitmap contains all the glyphs packed side by side (in order of
     51 * @c gfx_font_t.glyphs). This is to conserve space and number of bitmaps
     52 * used. The baselines of the glyphs are not mutually aligned.
     53 * For each glyph @c gfx_glyph_t.origin designates
     54 * pen start point (and thus the position of the baseline).
    4755 */
    4856struct gfx_font {
     
    5361        /** Glyphs */
    5462        list_t glyphs;
     63        /** Font bitmap */
     64        gfx_bitmap_t *bitmap;
     65        /** Bitmap rectangle */
     66        gfx_rect_t rect;
    5567};
     68
     69extern errno_t gfx_font_splice_at_glyph(gfx_font_t *, gfx_glyph_t *,
     70    gfx_coord_t, gfx_coord_t);
    5671
    5772#endif
  • uspace/lib/gfxfont/private/glyph.h

    r5592c56 rd2100e2  
    3939
    4040#include <adt/list.h>
     41#include <gfx/coord.h>
    4142#include <types/gfx/glyph.h>
    4243
     
    5455        /** Text patterns (of gfx_glyph_pattern_t) */
    5556        list_t patterns;
     57        /** Rectangle within font bitmap containing the glyph */
     58        gfx_rect_t rect;
     59        /** Glyph origin within font bitmap (pen start point) */
     60        gfx_coord2_t origin;
    5661};
    5762
     
    6974};
    7075
     76extern errno_t gfx_glyph_transfer(gfx_glyph_t *, gfx_coord_t, gfx_bitmap_t *,
     77    gfx_rect_t *);
     78
    7179#endif
    7280
  • uspace/lib/gfxfont/src/font.c

    r5592c56 rd2100e2  
    3737#include <assert.h>
    3838#include <errno.h>
     39#include <gfx/bitmap.h>
    3940#include <gfx/font.h>
    4041#include <gfx/glyph.h>
     
    7071{
    7172        gfx_font_t *font;
     73        gfx_bitmap_params_t params;
    7274        errno_t rc;
    7375
     
    8183        if (rc != EOK) {
    8284                assert(rc == EINVAL);
     85                free(font);
     86                return rc;
     87        }
     88
     89        /* Create font bitmap */
     90        gfx_bitmap_params_init(&params);
     91        params.rect = font->rect;
     92
     93        rc = gfx_bitmap_create(font->gc, &params, NULL, &font->bitmap);
     94        if (rc != EOK) {
    8395                free(font);
    8496                return rc;
     
    190202}
    191203
     204/** Replace glyph graphic with empty space of specified width.
     205 *
     206 * This is used to resize a glyph in the font bitmap. This changes
     207 * the bitmap widht and might also make the bitmap taller.
     208 * Width and height of the glyph is also adjusted accordingly.
     209 *
     210 * @param font Font
     211 * @param glyph Glyph to replace
     212 * @param width Width of replacement space
     213 * @param height Height of replacement space
     214 */
     215errno_t gfx_font_splice_at_glyph(gfx_font_t *font, gfx_glyph_t *glyph,
     216    gfx_coord_t width, gfx_coord_t height)
     217{
     218        gfx_glyph_t *g;
     219        gfx_bitmap_t *nbitmap;
     220        gfx_bitmap_params_t params;
     221        gfx_coord_t dwidth;
     222        errno_t rc;
     223
     224        /* Change of width of glyph */
     225        dwidth = width - (glyph->rect.p1.x - glyph->rect.p0.x);
     226
     227        /* Create new font bitmap, wider by dwidth pixels */
     228        gfx_bitmap_params_init(&params);
     229        params.rect = font->rect;
     230        params.rect.p1.x += dwidth;
     231        if (height > params.rect.p1.y)
     232                params.rect.p1.y = height;
     233
     234        rc = gfx_bitmap_create(font->gc, &params, NULL, &nbitmap);
     235        if (rc != EOK)
     236                goto error;
     237
     238        /* Transfer glyphs before @a glyph */
     239        g = gfx_font_first_glyph(font);
     240        while (g != glyph) {
     241                assert(g != NULL);
     242
     243                rc = gfx_glyph_transfer(g, 0, nbitmap, &params.rect);
     244                if (rc != EOK)
     245                        goto error;
     246
     247                g = gfx_font_next_glyph(g);
     248        }
     249
     250        /* Skip @a glyph */
     251        g = gfx_font_next_glyph(g);
     252
     253        /* Transfer glyphs after glyph */
     254        while (g != NULL) {
     255                rc = gfx_glyph_transfer(g, dwidth, nbitmap, &params.rect);
     256                if (rc != EOK)
     257                        goto error;
     258
     259                /* Update glyph coordinates */
     260                g->rect.p0.x += dwidth;
     261                g->rect.p1.x += dwidth;
     262                g->origin.x += dwidth;
     263
     264                g = gfx_font_next_glyph(g);
     265        }
     266
     267        /* Update glyph width and height */
     268        glyph->rect.p1.x = glyph->rect.p0.x + width;
     269        glyph->rect.p1.y = glyph->rect.p0.y + height;
     270
     271        /* Update font bitmap */
     272        gfx_bitmap_destroy(font->bitmap);
     273        font->bitmap = nbitmap;
     274        font->rect = params.rect;
     275
     276        return EOK;
     277error:
     278        if (nbitmap != NULL)
     279                gfx_bitmap_destroy(nbitmap);
     280        return rc;
     281}
     282
    192283/** @}
    193284 */
  • uspace/lib/gfxfont/src/glyph.c

    r5592c56 rd2100e2  
    3636#include <assert.h>
    3737#include <errno.h>
     38#include <gfx/bitmap.h>
    3839#include <gfx/glyph.h>
     40#include <io/pixelmap.h>
    3941#include <mem.h>
    4042#include <stdlib.h>
     
    252254}
    253255
     256/** Transfer glyph to new font bitmap.
     257 *
     258 * @param glyph Glyph
     259 * @param offs Offset in new font bitmap
     260 * @param dest New font bitmap
     261 * @param drect Bounding rectangle for @a dest
     262 *
     263 * @return EOK on success or an error code
     264 */
     265errno_t gfx_glyph_transfer(gfx_glyph_t *glyph, gfx_coord_t offs,
     266    gfx_bitmap_t *dest, gfx_rect_t *drect)
     267{
     268        pixelmap_t smap;
     269        pixelmap_t dmap;
     270        gfx_bitmap_alloc_t salloc;
     271        gfx_bitmap_alloc_t dalloc;
     272        gfx_coord_t x, y;
     273        pixel_t pixel;
     274        errno_t rc;
     275
     276        rc = gfx_bitmap_get_alloc(glyph->font->bitmap, &salloc);
     277        if (rc != EOK)
     278                return rc;
     279
     280        rc = gfx_bitmap_get_alloc(dest, &dalloc);
     281        if (rc != EOK)
     282                return rc;
     283
     284        smap.width = glyph->font->rect.p1.x;
     285        smap.height = glyph->font->rect.p1.y;
     286        smap.data = salloc.pixels;
     287
     288        dmap.width = drect->p1.x;
     289        dmap.height = drect->p1.y;
     290        dmap.data = dalloc.pixels;
     291
     292        for (y = drect->p0.y; y < drect->p1.y; y++) {
     293                for (x = drect->p0.x; x < drect->p1.x; x++) {
     294                        pixel = pixelmap_get_pixel(&smap, x, y);
     295                        pixelmap_put_pixel(&dmap, x + offs, y, pixel);
     296                }
     297        }
     298
     299        return EOK;
     300}
     301
    254302/** @}
    255303 */
  • uspace/lib/gfxfont/src/glyph_bmp.c

    r5592c56 rd2100e2  
    3535
    3636#include <errno.h>
     37#include <gfx/bitmap.h>
    3738#include <gfx/coord.h>
     39#include <gfx/font.h>
    3840#include <gfx/glyph_bmp.h>
     41#include <io/pixelmap.h>
    3942#include <stdlib.h>
     43#include "../private/font.h"
     44#include "../private/glyph.h"
    4045#include "../private/glyph_bmp.h"
    4146
     
    5055errno_t gfx_glyph_bmp_open(gfx_glyph_t *glyph, gfx_glyph_bmp_t **rbmp)
    5156{
     57        gfx_font_t *font = glyph->font;
    5258        gfx_glyph_bmp_t *bmp;
     59        pixelmap_t pmap;
     60        gfx_bitmap_alloc_t alloc;
     61        gfx_coord_t x, y;
     62        pixel_t pixel;
     63        errno_t rc;
    5364
    5465        bmp = calloc(1, sizeof(gfx_glyph_bmp_t));
     
    5869        bmp->rect.p0.x = 0;
    5970        bmp->rect.p0.y = 0;
    60         bmp->rect.p1.x = 0;
    61         bmp->rect.p1.y = 0;
    62         bmp->pixels = NULL;
     71        bmp->rect.p1.x = glyph->rect.p1.x - glyph->rect.p0.x;
     72        bmp->rect.p1.y = glyph->rect.p1.y - glyph->rect.p0.y;
     73
     74        bmp->pixels = calloc(bmp->rect.p1.x * bmp->rect.p1.y, sizeof(int));
     75        if (bmp->pixels == NULL) {
     76                free(bmp);
     77                return ENOMEM;
     78        }
     79
     80        rc = gfx_bitmap_get_alloc(font->bitmap, &alloc);
     81        if (rc != EOK) {
     82                free(bmp->pixels);
     83                free(bmp);
     84                return rc;
     85        }
     86
     87        assert(font->rect.p0.x == 0);
     88        assert(font->rect.p0.y == 0);
     89        pmap.width = font->rect.p1.x;
     90        pmap.height = font->rect.p1.y;
     91        pmap.data = alloc.pixels;
     92
     93        /* Copy pixels from font bitmap */
     94
     95        for (y = 0; y < bmp->rect.p1.y; y++) {
     96                for (x = 0; x < bmp->rect.p1.x; x++) {
     97                        pixel = pixelmap_get_pixel(&pmap, glyph->rect.p0.x + x,
     98                            glyph->rect.p0.y + y);
     99                        bmp->pixels[y * bmp->rect.p1.x + x] =
     100                            (pixel != 0) ? 1 : 0;
     101                }
     102        }
    63103
    64104        bmp->glyph = glyph;
     
    74114errno_t gfx_glyph_bmp_save(gfx_glyph_bmp_t *bmp)
    75115{
     116        gfx_glyph_t *glyph = bmp->glyph;
     117        gfx_font_t *font = glyph->font;
     118        gfx_coord_t x, y;
     119        pixel_t pixel;
     120        pixelmap_t pmap;
     121        gfx_bitmap_alloc_t alloc;
     122        errno_t rc;
     123
     124        /*
     125         * Replace glyph with empty space in the font bitmap, the width
     126         * of the empty equal to new glyph bitmap width. The glyph width
     127         * is adjusted.
     128         */
     129        rc = gfx_font_splice_at_glyph(font, glyph,
     130            bmp->rect.p1.x - bmp->rect.p0.x, bmp->rect.p1.y - bmp->rect.p0.y);
     131        if (rc != EOK)
     132                return rc;
     133
     134        rc = gfx_bitmap_get_alloc(font->bitmap, &alloc);
     135        if (rc != EOK)
     136                return rc;
     137
     138        assert(font->rect.p0.x == 0);
     139        assert(font->rect.p0.y == 0);
     140        pmap.width = font->rect.p1.x;
     141        pmap.height = font->rect.p1.y;
     142        pmap.data = alloc.pixels;
     143
     144        /* Copy pixels to font bitmap */
     145
     146        for (y = 0; y < bmp->rect.p1.y; y++) {
     147                for (x = 0; x < bmp->rect.p1.x; x++) {
     148                        pixel = bmp->pixels[y * bmp->rect.p1.x + x] ?
     149                            PIXEL(255, 255, 255, 255) : PIXEL(0, 0, 0, 0);
     150                        pixelmap_put_pixel(&pmap, glyph->rect.p0.x + x,
     151                            glyph->rect.p0.y + y, pixel);
     152                }
     153        }
     154
    76155        return EOK;
    77156}
  • uspace/lib/gfxfont/test/font.c

    r5592c56 rd2100e2  
    2929#include <gfx/context.h>
    3030#include <gfx/font.h>
     31#include <gfx/glyph.h>
    3132#include <pcut/pcut.h>
     33#include "../private/font.h"
    3234
    3335PCUT_INIT;
     
    3739static errno_t testgc_set_color(void *, gfx_color_t *);
    3840static errno_t testgc_fill_rect(void *, gfx_rect_t *);
     41static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
     42    gfx_bitmap_alloc_t *, void **);
     43static errno_t testgc_bitmap_destroy(void *);
     44static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     45static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    3946
    4047static gfx_context_ops_t test_ops = {
    4148        .set_color = testgc_set_color,
    42         .fill_rect = testgc_fill_rect
     49        .fill_rect = testgc_fill_rect,
     50        .bitmap_create = testgc_bitmap_create,
     51        .bitmap_destroy = testgc_bitmap_destroy,
     52        .bitmap_render = testgc_bitmap_render,
     53        .bitmap_get_alloc = testgc_bitmap_get_alloc
    4354};
     55
     56typedef struct {
     57        gfx_bitmap_params_t bm_params;
     58        void *bm_pixels;
     59        gfx_rect_t bm_srect;
     60        gfx_coord2_t bm_offs;
     61} test_gc_t;
     62
     63typedef struct {
     64        test_gc_t *tgc;
     65        gfx_bitmap_alloc_t alloc;
     66        bool myalloc;
     67} testgc_bitmap_t;
    4468
    4569/** Test creating and destroying font */
     
    4973        gfx_font_t *font;
    5074        gfx_context_t *gc;
    51         errno_t rc;
    52 
    53         rc = gfx_context_new(&test_ops, NULL, &gc);
     75        test_gc_t tgc;
     76        errno_t rc;
     77
     78        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
    5479        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    5580
     
    7095        gfx_font_t *font;
    7196        gfx_context_t *gc;
    72         errno_t rc;
    73 
    74         rc = gfx_context_new(&test_ops, NULL, &gc);
     97        test_gc_t tgc;
     98        errno_t rc;
     99
     100        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
    75101        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    76102
     
    101127        gfx_font_t *font;
    102128        gfx_context_t *gc;
    103         errno_t rc;
    104 
    105         rc = gfx_context_new(&test_ops, NULL, &gc);
     129        test_gc_t tgc;
     130        errno_t rc;
     131
     132        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
    106133        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    107134
     
    136163{
    137164        gfx_font_metrics_t metrics;
     165        gfx_glyph_metrics_t gmetrics;
    138166        gfx_font_t *font;
    139167        gfx_context_t *gc;
    140168        gfx_glyph_t *glyph;
    141         errno_t rc;
    142 
    143         rc = gfx_context_new(&test_ops, NULL, &gc);
    144         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    145 
    146         gfx_font_metrics_init(&metrics);
    147 
    148         rc = gfx_font_create(gc, &metrics, &font);
    149         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    150 
     169        gfx_glyph_t *gfirst;
     170        test_gc_t tgc;
     171        errno_t rc;
     172
     173        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
     174        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     175
     176        gfx_font_metrics_init(&metrics);
     177
     178        rc = gfx_font_create(gc, &metrics, &font);
     179        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     180
     181        /* Should get NULL since there is no glyph in the font */
    151182        glyph = gfx_font_first_glyph(font);
    152183        PCUT_ASSERT_NULL(glyph);
    153184
     185        /* Now add one */
     186        gfx_glyph_metrics_init(&gmetrics);
     187        rc = gfx_glyph_create(font, &gmetrics, &glyph);
     188        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     189
     190        /* gfx_font_first_glyph() should return the same */
     191        gfirst = gfx_font_first_glyph(font);
     192        PCUT_ASSERT_EQUALS(glyph, gfirst);
     193
     194        gfx_glyph_destroy(glyph);
    154195        gfx_font_destroy(font);
    155196        rc = gfx_context_delete(gc);
     
    160201PCUT_TEST(next_glyph)
    161202{
    162         /* TODO */
     203        gfx_font_metrics_t metrics;
     204        gfx_glyph_metrics_t gmetrics;
     205        gfx_font_t *font;
     206        gfx_context_t *gc;
     207        gfx_glyph_t *glyph1;
     208        gfx_glyph_t *glyph2;
     209        gfx_glyph_t *gfirst;
     210        gfx_glyph_t *gsecond;
     211        test_gc_t tgc;
     212        errno_t rc;
     213
     214        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
     215        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     216
     217        gfx_font_metrics_init(&metrics);
     218
     219        rc = gfx_font_create(gc, &metrics, &font);
     220        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     221
     222        /* Add first glyph */
     223        gfx_glyph_metrics_init(&gmetrics);
     224        rc = gfx_glyph_create(font, &gmetrics, &glyph1);
     225        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     226
     227        /* Add second glyph */
     228        gfx_glyph_metrics_init(&gmetrics);
     229        rc = gfx_glyph_create(font, &gmetrics, &glyph2);
     230        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     231
     232        /* gfx_font_first_glyph() should return glyph1 */
     233        gfirst = gfx_font_first_glyph(font);
     234        PCUT_ASSERT_EQUALS(glyph1, gfirst);
     235
     236        /* gfx_font_next_glyph() should return glyph2 */
     237        gsecond = gfx_font_next_glyph(gfirst);
     238        PCUT_ASSERT_EQUALS(glyph2, gsecond);
     239
     240        gfx_glyph_destroy(glyph1);
     241        gfx_glyph_destroy(glyph2);
     242        gfx_font_destroy(font);
     243        rc = gfx_context_delete(gc);
     244        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    163245}
    164246
     
    171253        gfx_glyph_t *glyph;
    172254        size_t bytes;
    173         errno_t rc;
    174 
    175         rc = gfx_context_new(&test_ops, NULL, &gc);
     255        test_gc_t tgc;
     256        errno_t rc;
     257
     258        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
    176259        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    177260
     
    189272}
    190273
     274/** Test gfx_font_splice_at_glyph() */
     275PCUT_TEST(splice_at_glyph)
     276{
     277        gfx_font_metrics_t fmetrics;
     278        gfx_font_t *font;
     279        gfx_glyph_metrics_t gmetrics;
     280        gfx_glyph_t *glyph;
     281        gfx_context_t *gc;
     282        test_gc_t tgc;
     283        errno_t rc;
     284
     285        rc = gfx_context_new(&test_ops, (void *)&tgc, &gc);
     286        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     287
     288        gfx_font_metrics_init(&fmetrics);
     289        rc = gfx_font_create(gc, &fmetrics, &font);
     290        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     291
     292        gfx_glyph_metrics_init(&gmetrics);
     293        rc = gfx_glyph_create(font, &gmetrics, &glyph);
     294        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     295
     296        rc = gfx_font_splice_at_glyph(font, glyph, 10, 10);
     297        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     298
     299        gfx_glyph_destroy(glyph);
     300
     301        gfx_font_destroy(font);
     302        rc = gfx_context_delete(gc);
     303        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     304}
     305
    191306static errno_t testgc_set_color(void *arg, gfx_color_t *color)
    192307{
     
    199314}
    200315
     316static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     317    gfx_bitmap_alloc_t *alloc, void **rbm)
     318{
     319        test_gc_t *tgc = (test_gc_t *) arg;
     320        testgc_bitmap_t *tbm;
     321
     322        tbm = calloc(1, sizeof(testgc_bitmap_t));
     323        if (tbm == NULL)
     324                return ENOMEM;
     325
     326        if (alloc == NULL) {
     327                tbm->alloc.pitch = (params->rect.p1.x - params->rect.p0.x) *
     328                    sizeof(uint32_t);
     329                tbm->alloc.off0 = 0;
     330                tbm->alloc.pixels = calloc(sizeof(uint32_t),
     331                    tbm->alloc.pitch * (params->rect.p1.y - params->rect.p0.y));
     332                tbm->myalloc = true;
     333                if (tbm->alloc.pixels == NULL) {
     334                        free(tbm);
     335                        return ENOMEM;
     336                }
     337        } else {
     338                tbm->alloc = *alloc;
     339        }
     340
     341        tbm->tgc = tgc;
     342        tgc->bm_params = *params;
     343        tgc->bm_pixels = tbm->alloc.pixels;
     344        *rbm = (void *)tbm;
     345        return EOK;
     346}
     347
     348static errno_t testgc_bitmap_destroy(void *bm)
     349{
     350        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     351        if (tbm->myalloc)
     352                free(tbm->alloc.pixels);
     353        free(tbm);
     354        return EOK;
     355}
     356
     357static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
     358    gfx_coord2_t *offs)
     359{
     360        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     361        tbm->tgc->bm_srect = *srect;
     362        tbm->tgc->bm_offs = *offs;
     363        return EOK;
     364}
     365
     366static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     367{
     368        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     369        *alloc = tbm->alloc;
     370        return EOK;
     371}
     372
    201373PCUT_EXPORT(font);
  • uspace/lib/gfxfont/test/glyph.c

    r5592c56 rd2100e2  
    2727 */
    2828
     29#include <gfx/bitmap.h>
    2930#include <gfx/context.h>
    3031#include <gfx/font.h>
    3132#include <gfx/glyph.h>
     33#include <gfx/glyph_bmp.h>
     34#include <io/pixelmap.h>
    3235#include <pcut/pcut.h>
    3336#include <stdbool.h>
    3437#include <str.h>
     38#include "../private/glyph.h"
    3539
    3640PCUT_INIT;
     
    4044static errno_t testgc_set_color(void *, gfx_color_t *);
    4145static errno_t testgc_fill_rect(void *, gfx_rect_t *);
     46static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
     47    gfx_bitmap_alloc_t *, void **);
     48static errno_t testgc_bitmap_destroy(void *);
     49static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     50static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    4251
    4352static gfx_context_ops_t test_ops = {
    4453        .set_color = testgc_set_color,
    45         .fill_rect = testgc_fill_rect
     54        .fill_rect = testgc_fill_rect,
     55        .bitmap_create = testgc_bitmap_create,
     56        .bitmap_destroy = testgc_bitmap_destroy,
     57        .bitmap_render = testgc_bitmap_render,
     58        .bitmap_get_alloc = testgc_bitmap_get_alloc
    4659};
     60
     61typedef struct {
     62        gfx_bitmap_params_t bm_params;
     63        void *bm_pixels;
     64        gfx_rect_t bm_srect;
     65        gfx_coord2_t bm_offs;
     66} test_gc_t;
     67
     68typedef struct {
     69        test_gc_t *tgc;
     70        gfx_bitmap_alloc_t alloc;
     71        bool myalloc;
     72} testgc_bitmap_t;
    4773
    4874/** Test creating and destroying glyph */
     
    5480        gfx_glyph_t *glyph;
    5581        gfx_context_t *gc;
    56         errno_t rc;
    57 
    58         rc = gfx_context_new(&test_ops, NULL, &gc);
     82        test_gc_t tgc;
     83        errno_t rc;
     84
     85        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    5986        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    6087
     
    83110        gfx_glyph_metrics_t rmetrics;
    84111        gfx_context_t *gc;
    85         errno_t rc;
    86 
    87         rc = gfx_context_new(&test_ops, NULL, &gc);
     112        test_gc_t tgc;
     113        errno_t rc;
     114
     115        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    88116        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    89117
     
    118146        gfx_glyph_metrics_t rmetrics;
    119147        gfx_context_t *gc;
    120         errno_t rc;
    121 
    122         rc = gfx_context_new(&test_ops, NULL, &gc);
     148        test_gc_t tgc;
     149        errno_t rc;
     150
     151        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    123152        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    124153
     
    156185        gfx_glyph_t *glyph;
    157186        gfx_context_t *gc;
    158         errno_t rc;
    159 
    160         rc = gfx_context_new(&test_ops, NULL, &gc);
     187        test_gc_t tgc;
     188        errno_t rc;
     189
     190        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    161191        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    162192
     
    198228        gfx_glyph_t *glyph;
    199229        gfx_context_t *gc;
    200         errno_t rc;
    201 
    202         rc = gfx_context_new(&test_ops, NULL, &gc);
     230        test_gc_t tgc;
     231        errno_t rc;
     232
     233        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    203234        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    204235
     
    243274        gfx_glyph_t *glyph;
    244275        gfx_context_t *gc;
     276        test_gc_t tgc;
    245277        bool match;
    246278        size_t msize;
    247279        errno_t rc;
    248280
    249         rc = gfx_context_new(&test_ops, NULL, &gc);
     281        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    250282        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    251283
     
    296328        gfx_glyph_t *glyph;
    297329        gfx_context_t *gc;
     330        test_gc_t tgc;
    298331        gfx_glyph_pattern_t *pat;
    299332        errno_t rc;
    300333
    301         rc = gfx_context_new(&test_ops, NULL, &gc);
     334        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    302335        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    303336
     
    340373        gfx_glyph_t *glyph;
    341374        gfx_context_t *gc;
     375        test_gc_t tgc;
    342376        gfx_glyph_pattern_t *pat;
    343377        const char *pstr;
    344378        errno_t rc;
    345379
    346         rc = gfx_context_new(&test_ops, NULL, &gc);
     380        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    347381        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    348382
     
    377411}
    378412
     413/** Test gfx_glyph_transfer() */
     414PCUT_TEST(transfer)
     415{
     416        gfx_font_metrics_t fmetrics;
     417        gfx_font_t *font;
     418        gfx_glyph_metrics_t gmetrics;
     419        gfx_glyph_t *glyph;
     420        gfx_context_t *gc;
     421        gfx_bitmap_t *bitmap;
     422        gfx_bitmap_params_t params;
     423        gfx_bitmap_alloc_t alloc;
     424        gfx_glyph_bmp_t *bmp;
     425        pixelmap_t pmap;
     426        pixel_t pixel;
     427        test_gc_t tgc;
     428        errno_t rc;
     429
     430        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
     431        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     432
     433        gfx_font_metrics_init(&fmetrics);
     434        rc = gfx_font_create(gc, &fmetrics, &font);
     435        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     436
     437        gfx_glyph_metrics_init(&gmetrics);
     438        gmetrics.advance = 1;
     439
     440        rc = gfx_glyph_create(font, &gmetrics, &glyph);
     441        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     442
     443        /*
     444         * We need to fill some pixels of the glyph.
     445         * We'll use the glyph bitmap for that.
     446         * That means this test won't pass unless glyph
     447         * bitmap works.
     448         */
     449
     450        rc = gfx_glyph_bmp_open(glyph, &bmp);
     451        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     452        PCUT_ASSERT_NOT_NULL(bmp);
     453
     454        rc = gfx_glyph_bmp_setpix(bmp, 0, 0, 1);
     455        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     456
     457        rc = gfx_glyph_bmp_setpix(bmp, 1, 1, 1);
     458        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     459
     460        rc = gfx_glyph_bmp_save(bmp);
     461        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     462        gfx_glyph_bmp_close(bmp);
     463
     464        /* Now create a new bitmap */
     465
     466        gfx_bitmap_params_init(&params);
     467        params.rect.p0.x = 0;
     468        params.rect.p0.y = 0;
     469        params.rect.p1.x = 10;
     470        params.rect.p1.y = 10;
     471        rc = gfx_bitmap_create(gc, &params, NULL, &bitmap);
     472        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     473
     474        rc = gfx_bitmap_get_alloc(bitmap, &alloc);
     475        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     476
     477        /* Transfer the glyph to new bitmap */
     478        rc = gfx_glyph_transfer(glyph, 0, bitmap, &params.rect);
     479        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     480
     481        /* Now let's read pixels from the new bitmap */
     482        pmap.width = params.rect.p1.x;
     483        pmap.height = params.rect.p1.y;
     484        pmap.data = alloc.pixels;
     485
     486        pixel = pixelmap_get_pixel(&pmap, 0, 0);
     487        PCUT_ASSERT_INT_EQUALS(PIXEL(255, 255, 255, 255), pixel);
     488
     489        pixel = pixelmap_get_pixel(&pmap, 1, 1);
     490        PCUT_ASSERT_INT_EQUALS(PIXEL(255, 255, 255, 255), pixel);
     491
     492        pixel = pixelmap_get_pixel(&pmap, 1, 0);
     493        PCUT_ASSERT_INT_EQUALS(PIXEL(0, 0, 0, 0), pixel);
     494
     495        pixel = pixelmap_get_pixel(&pmap, 0, 1);
     496        PCUT_ASSERT_INT_EQUALS(PIXEL(0, 0, 0, 0), pixel);
     497
     498        gfx_glyph_destroy(glyph);
     499
     500        gfx_font_destroy(font);
     501        rc = gfx_context_delete(gc);
     502        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     503}
     504
    379505static errno_t testgc_set_color(void *arg, gfx_color_t *color)
    380506{
     
    387513}
    388514
     515static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     516    gfx_bitmap_alloc_t *alloc, void **rbm)
     517{
     518        test_gc_t *tgc = (test_gc_t *) arg;
     519        testgc_bitmap_t *tbm;
     520
     521        tbm = calloc(1, sizeof(testgc_bitmap_t));
     522        if (tbm == NULL)
     523                return ENOMEM;
     524
     525        if (alloc == NULL) {
     526                tbm->alloc.pitch = (params->rect.p1.x - params->rect.p0.x) *
     527                    sizeof(uint32_t);
     528                tbm->alloc.off0 = 0;
     529                tbm->alloc.pixels = calloc(sizeof(uint32_t),
     530                    tbm->alloc.pitch * (params->rect.p1.y - params->rect.p0.y));
     531                tbm->myalloc = true;
     532                if (tbm->alloc.pixels == NULL) {
     533                        free(tbm);
     534                        return ENOMEM;
     535                }
     536        } else {
     537                tbm->alloc = *alloc;
     538        }
     539
     540        tbm->tgc = tgc;
     541        tgc->bm_params = *params;
     542        tgc->bm_pixels = tbm->alloc.pixels;
     543        *rbm = (void *)tbm;
     544        return EOK;
     545}
     546
     547static errno_t testgc_bitmap_destroy(void *bm)
     548{
     549        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     550        if (tbm->myalloc)
     551                free(tbm->alloc.pixels);
     552        free(tbm);
     553        return EOK;
     554}
     555
     556static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
     557    gfx_coord2_t *offs)
     558{
     559        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     560        tbm->tgc->bm_srect = *srect;
     561        tbm->tgc->bm_offs = *offs;
     562        return EOK;
     563}
     564
     565static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     566{
     567        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     568        *alloc = tbm->alloc;
     569        return EOK;
     570}
     571
    389572PCUT_EXPORT(glyph);
  • uspace/lib/gfxfont/test/glyph_bmp.c

    r5592c56 rd2100e2  
    3939static errno_t testgc_set_color(void *, gfx_color_t *);
    4040static errno_t testgc_fill_rect(void *, gfx_rect_t *);
     41static errno_t testgc_bitmap_create(void *, gfx_bitmap_params_t *,
     42    gfx_bitmap_alloc_t *, void **);
     43static errno_t testgc_bitmap_destroy(void *);
     44static errno_t testgc_bitmap_render(void *, gfx_rect_t *, gfx_coord2_t *);
     45static errno_t testgc_bitmap_get_alloc(void *, gfx_bitmap_alloc_t *);
    4146
    4247static gfx_context_ops_t test_ops = {
    4348        .set_color = testgc_set_color,
    44         .fill_rect = testgc_fill_rect
     49        .fill_rect = testgc_fill_rect,
     50        .bitmap_create = testgc_bitmap_create,
     51        .bitmap_destroy = testgc_bitmap_destroy,
     52        .bitmap_render = testgc_bitmap_render,
     53        .bitmap_get_alloc = testgc_bitmap_get_alloc
    4554};
     55
     56typedef struct {
     57        gfx_bitmap_params_t bm_params;
     58        void *bm_pixels;
     59        gfx_rect_t bm_srect;
     60        gfx_coord2_t bm_offs;
     61} test_gc_t;
     62
     63typedef struct {
     64        test_gc_t *tgc;
     65        gfx_bitmap_alloc_t alloc;
     66        bool myalloc;
     67} testgc_bitmap_t;
    4668
    4769/** Test opening and closing glyph bitmap */
     
    5476        gfx_context_t *gc;
    5577        gfx_glyph_bmp_t *bmp;
     78        test_gc_t tgc;
    5679        errno_t rc;
    5780
    58         rc = gfx_context_new(&test_ops, NULL, &gc);
     81        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    5982        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    6083
     
    86109/** Test glyph_bmp_save() */
    87110PCUT_TEST(save)
    88 {
    89         gfx_font_metrics_t fmetrics;
    90         gfx_font_t *font;
    91         gfx_glyph_metrics_t gmetrics;
    92         gfx_glyph_t *glyph;
    93         gfx_context_t *gc;
    94         gfx_glyph_bmp_t *bmp;
    95         errno_t rc;
    96 
    97         rc = gfx_context_new(&test_ops, NULL, &gc);
    98         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    99 
    100         gfx_font_metrics_init(&fmetrics);
    101         rc = gfx_font_create(gc, &fmetrics, &font);
    102         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    103 
    104         gfx_glyph_metrics_init(&gmetrics);
    105         gmetrics.advance = 1;
    106 
    107         rc = gfx_glyph_create(font, &gmetrics, &glyph);
    108         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    109 
    110         bmp = NULL;
    111 
    112         rc = gfx_glyph_bmp_open(glyph, &bmp);
    113         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    114         PCUT_ASSERT_NOT_NULL(bmp);
    115 
    116         /* TODO: Need a test to verify that save actually worked */
    117         rc = gfx_glyph_bmp_save(bmp);
    118         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    119 
    120         gfx_glyph_bmp_close(bmp);
    121 
    122         gfx_glyph_destroy(glyph);
    123 
    124         gfx_font_destroy(font);
    125         rc = gfx_context_delete(gc);
    126         PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    127 }
    128 
    129 /** Test glyph_bmp_getpix() */
    130 PCUT_TEST(getpix)
    131111{
    132112        gfx_font_metrics_t fmetrics;
     
    137117        gfx_glyph_bmp_t *bmp;
    138118        int pix;
     119        test_gc_t tgc;
    139120        errno_t rc;
    140121
    141         rc = gfx_context_new(&test_ops, NULL, &gc);
     122        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    142123        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    143124
     
    154135        bmp = NULL;
    155136
     137        /* Open bitmap and set some pixels */
     138
     139        rc = gfx_glyph_bmp_open(glyph, &bmp);
     140        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     141        PCUT_ASSERT_NOT_NULL(bmp);
     142
     143        rc = gfx_glyph_bmp_setpix(bmp, 0, 0, 1);
     144        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     145
     146        rc = gfx_glyph_bmp_setpix(bmp, 1, 1, 1);
     147        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     148
     149        rc = gfx_glyph_bmp_save(bmp);
     150        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     151
     152        gfx_glyph_bmp_close(bmp);
     153        bmp = NULL;
     154
     155        /* Re-open the saved bimap and verify pixel values were preserved */
     156
    156157        rc = gfx_glyph_bmp_open(glyph, &bmp);
    157158        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     
    159160
    160161        pix = gfx_glyph_bmp_getpix(bmp, 0, 0);
     162        PCUT_ASSERT_INT_EQUALS(1, pix);
     163
     164        pix = gfx_glyph_bmp_getpix(bmp, 1, 1);
     165        PCUT_ASSERT_INT_EQUALS(1, pix);
     166
     167        pix = gfx_glyph_bmp_getpix(bmp, 1, 0);
    161168        PCUT_ASSERT_INT_EQUALS(0, pix);
    162169
    163         gfx_glyph_bmp_close(bmp);
    164 
     170        pix = gfx_glyph_bmp_getpix(bmp, 0, 1);
     171        PCUT_ASSERT_INT_EQUALS(0, pix);
     172
     173        gfx_glyph_bmp_close(bmp);
    165174        gfx_glyph_destroy(glyph);
    166175
     
    170179}
    171180
    172 /** Test glyph_bmp_setpix() can flip pixel value both ways */
    173 PCUT_TEST(setpix_flip)
     181/** Test glyph_bmp_getpix() */
     182PCUT_TEST(getpix)
    174183{
    175184        gfx_font_metrics_t fmetrics;
     
    179188        gfx_context_t *gc;
    180189        gfx_glyph_bmp_t *bmp;
     190        test_gc_t tgc;
    181191        int pix;
    182192        errno_t rc;
    183193
    184         rc = gfx_context_new(&test_ops, NULL, &gc);
     194        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
     195        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     196
     197        gfx_font_metrics_init(&fmetrics);
     198        rc = gfx_font_create(gc, &fmetrics, &font);
     199        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     200
     201        gfx_glyph_metrics_init(&gmetrics);
     202        gmetrics.advance = 1;
     203
     204        rc = gfx_glyph_create(font, &gmetrics, &glyph);
     205        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     206
     207        bmp = NULL;
     208
     209        rc = gfx_glyph_bmp_open(glyph, &bmp);
     210        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     211        PCUT_ASSERT_NOT_NULL(bmp);
     212
     213        pix = gfx_glyph_bmp_getpix(bmp, 0, 0);
     214        PCUT_ASSERT_INT_EQUALS(0, pix);
     215
     216        gfx_glyph_bmp_close(bmp);
     217
     218        gfx_glyph_destroy(glyph);
     219
     220        gfx_font_destroy(font);
     221        rc = gfx_context_delete(gc);
     222        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     223}
     224
     225/** Test glyph_bmp_setpix() can flip pixel value both ways */
     226PCUT_TEST(setpix_flip)
     227{
     228        gfx_font_metrics_t fmetrics;
     229        gfx_font_t *font;
     230        gfx_glyph_metrics_t gmetrics;
     231        gfx_glyph_t *glyph;
     232        gfx_context_t *gc;
     233        gfx_glyph_bmp_t *bmp;
     234        test_gc_t tgc;
     235        int pix;
     236        errno_t rc;
     237
     238        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    185239        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    186240
     
    235289        gfx_glyph_bmp_t *bmp;
    236290        gfx_coord_t x, y;
     291        test_gc_t tgc;
    237292        int pix;
    238293        errno_t rc;
    239294
    240         rc = gfx_context_new(&test_ops, NULL, &gc);
     295        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
    241296        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
    242297
     
    303358}
    304359
     360static errno_t testgc_bitmap_create(void *arg, gfx_bitmap_params_t *params,
     361    gfx_bitmap_alloc_t *alloc, void **rbm)
     362{
     363        test_gc_t *tgc = (test_gc_t *) arg;
     364        testgc_bitmap_t *tbm;
     365
     366        tbm = calloc(1, sizeof(testgc_bitmap_t));
     367        if (tbm == NULL)
     368                return ENOMEM;
     369
     370        if (alloc == NULL) {
     371                tbm->alloc.pitch = (params->rect.p1.x - params->rect.p0.x) *
     372                    sizeof(uint32_t);
     373                tbm->alloc.off0 = 0;
     374                tbm->alloc.pixels = calloc(sizeof(uint32_t),
     375                    tbm->alloc.pitch * (params->rect.p1.y - params->rect.p0.y));
     376                tbm->myalloc = true;
     377                if (tbm->alloc.pixels == NULL) {
     378                        free(tbm);
     379                        return ENOMEM;
     380                }
     381        } else {
     382                tbm->alloc = *alloc;
     383        }
     384
     385        tbm->tgc = tgc;
     386        tgc->bm_params = *params;
     387        tgc->bm_pixels = tbm->alloc.pixels;
     388        *rbm = (void *)tbm;
     389        return EOK;
     390}
     391
     392static errno_t testgc_bitmap_destroy(void *bm)
     393{
     394        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     395        if (tbm->myalloc)
     396                free(tbm->alloc.pixels);
     397        free(tbm);
     398        return EOK;
     399}
     400
     401static errno_t testgc_bitmap_render(void *bm, gfx_rect_t *srect,
     402    gfx_coord2_t *offs)
     403{
     404        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     405        tbm->tgc->bm_srect = *srect;
     406        tbm->tgc->bm_offs = *offs;
     407        return EOK;
     408}
     409
     410static errno_t testgc_bitmap_get_alloc(void *bm, gfx_bitmap_alloc_t *alloc)
     411{
     412        testgc_bitmap_t *tbm = (testgc_bitmap_t *)bm;
     413        *alloc = tbm->alloc;
     414        return EOK;
     415}
     416
    305417PCUT_EXPORT(glyph_bmp);
Note: See TracChangeset for help on using the changeset viewer.