Changeset dd65f4f7 in mainline


Ignore:
Timestamp:
2020-09-27T09:26:41Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d8cdaf1b
Parents:
efca2e4
Message:

Only save minimum used rectangle of glyph bitmap

When the image becomes smaller (clearing pixels), we don't want to keep
saving zero pixels.

Location:
uspace/lib/gfxfont
Files:
3 edited

Legend:

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

    refca2e4 rdd65f4f7  
    3939
    4040#include <gfx/coord.h>
     41#include <types/gfx/glyph_bmp.h>
    4142
    4243/** Glyph bitmap
     
    5758};
    5859
     60extern void gfx_glyph_bmp_find_used_rect(gfx_glyph_bmp_t *, gfx_rect_t *);
     61
    5962#endif
    6063
  • uspace/lib/gfxfont/src/glyph_bmp.c

    refca2e4 rdd65f4f7  
    116116        gfx_font_t *font = glyph->font;
    117117        gfx_coord_t x, y;
     118        gfx_rect_t used_rect;
    118119        pixel_t pixel;
    119120        pixelmap_t pmap;
    120121        gfx_bitmap_alloc_t alloc;
    121122        errno_t rc;
     123
     124        /* Find actual rectangle being used */
     125        gfx_glyph_bmp_find_used_rect(bmp, &used_rect);
    122126
    123127        /*
     
    126130         * is adjusted.
    127131         */
    128         rc = gfx_font_splice_at_glyph(font, glyph, &bmp->rect);
     132        rc = gfx_font_splice_at_glyph(font, glyph, &used_rect);
    129133        if (rc != EOK)
    130134                return rc;
     
    142146        /* Copy pixels to font bitmap */
    143147
    144         for (y = bmp->rect.p0.y; y < bmp->rect.p1.y; y++) {
    145                 for (x = bmp->rect.p0.x; x < bmp->rect.p1.x; x++) {
     148        for (y = used_rect.p0.y; y < used_rect.p1.y; y++) {
     149                for (x = used_rect.p0.x; x < used_rect.p1.x; x++) {
    146150                        pixel = bmp->pixels[(y - bmp->rect.p0.y) *
    147151                            (bmp->rect.p1.x - bmp->rect.p0.x) +
     
    176180}
    177181
     182/** Find minimum rectangle covering all non-background pixels.
     183 *
     184 * @param bmp Glyph bitmap
     185 * @param rect Place to store rectangle
     186 */
     187void gfx_glyph_bmp_find_used_rect(gfx_glyph_bmp_t *bmp, gfx_rect_t *rect)
     188{
     189        gfx_coord_t x, y;
     190        gfx_coord2_t min;
     191        gfx_coord2_t max;
     192        bool anypix;
     193        int pix;
     194
     195        min.x = bmp->rect.p1.x;
     196        min.y = bmp->rect.p1.y;
     197        max.x = bmp->rect.p0.x;
     198        max.y = bmp->rect.p0.y;
     199
     200        anypix = false;
     201        for (y = bmp->rect.p0.y; y < bmp->rect.p1.y; y++) {
     202                for (x = bmp->rect.p0.x; x < bmp->rect.p1.x; x++) {
     203                        pix = gfx_glyph_bmp_getpix(bmp, x, y);
     204                        if (pix != 0) {
     205                                anypix = true;
     206                                if (x < min.x)
     207                                        min.x = x;
     208                                if (y < min.y)
     209                                        min.y = y;
     210                                if (x > max.x)
     211                                        max.x = x;
     212                                if (y > max.y)
     213                                        max.y = y;
     214                        }
     215                }
     216        }
     217
     218        if (anypix) {
     219                rect->p0.x = min.x;
     220                rect->p0.y = min.y;
     221                rect->p1.x = max.x + 1;
     222                rect->p1.y = max.y + 1;
     223        } else {
     224                rect->p0.x = 0;
     225                rect->p0.y = 0;
     226                rect->p1.x = 0;
     227                rect->p1.y = 0;
     228        }
     229}
     230
    178231/** Get pixel from glyph bitmap.
    179232 *
  • uspace/lib/gfxfont/test/glyph_bmp.c

    refca2e4 rdd65f4f7  
    3333#include <gfx/typeface.h>
    3434#include <pcut/pcut.h>
     35#include "../private/glyph_bmp.h"
    3536
    3637PCUT_INIT;
     
    477478        pix = gfx_glyph_bmp_getpix(bmp, 1, 1);
    478479        PCUT_ASSERT_INT_EQUALS(0, pix);
     480
     481        gfx_glyph_bmp_close(bmp);
     482
     483        gfx_glyph_destroy(glyph);
     484
     485        gfx_font_close(font);
     486        gfx_typeface_destroy(tface);
     487        rc = gfx_context_delete(gc);
     488        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     489}
     490
     491/** Test glyph_bmp_find_used_rect() find minimum used rectangle */
     492PCUT_TEST(find_used_rect)
     493{
     494        gfx_font_props_t fprops;
     495        gfx_font_metrics_t fmetrics;
     496        gfx_typeface_t *tface;
     497        gfx_font_t *font;
     498        gfx_glyph_metrics_t gmetrics;
     499        gfx_glyph_t *glyph;
     500        gfx_context_t *gc;
     501        gfx_glyph_bmp_t *bmp;
     502        gfx_rect_t rect;
     503        test_gc_t tgc;
     504        errno_t rc;
     505
     506        rc = gfx_context_new(&test_ops, (void *) &tgc, &gc);
     507        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     508
     509        rc = gfx_typeface_create(gc, &tface);
     510        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     511
     512        gfx_font_props_init(&fprops);
     513        gfx_font_metrics_init(&fmetrics);
     514        rc = gfx_font_create(tface, &fprops, &fmetrics, &font);
     515        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     516
     517        gfx_glyph_metrics_init(&gmetrics);
     518        gmetrics.advance = 1;
     519
     520        rc = gfx_glyph_create(font, &gmetrics, &glyph);
     521        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     522
     523        bmp = NULL;
     524
     525        rc = gfx_glyph_bmp_open(glyph, &bmp);
     526        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     527        PCUT_ASSERT_NOT_NULL(bmp);
     528
     529        /* Check used rectangle */
     530
     531        gfx_glyph_bmp_find_used_rect(bmp, &rect);
     532        PCUT_ASSERT_INT_EQUALS(0, rect.p0.x);
     533        PCUT_ASSERT_INT_EQUALS(0, rect.p0.y);
     534        PCUT_ASSERT_INT_EQUALS(0, rect.p1.x);
     535        PCUT_ASSERT_INT_EQUALS(0, rect.p1.y);
     536
     537        /* Set some pixels */
     538
     539        rc = gfx_glyph_bmp_setpix(bmp, -4, -5, 1);
     540        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     541
     542        rc = gfx_glyph_bmp_setpix(bmp, -2, -1, 1);
     543        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     544
     545        rc = gfx_glyph_bmp_setpix(bmp, 3, 4, 1);
     546        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     547
     548        rc = gfx_glyph_bmp_setpix(bmp, 7, 6, 1);
     549        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     550
     551        /* Check used rectangle */
     552
     553        gfx_glyph_bmp_find_used_rect(bmp, &rect);
     554        PCUT_ASSERT_INT_EQUALS(-4, rect.p0.x);
     555        PCUT_ASSERT_INT_EQUALS(-5, rect.p0.y);
     556        PCUT_ASSERT_INT_EQUALS(8, rect.p1.x);
     557        PCUT_ASSERT_INT_EQUALS(7, rect.p1.y);
     558
     559        /* Clear the corner pixels */
     560
     561        rc = gfx_glyph_bmp_setpix(bmp, -4, -5, 0);
     562        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     563
     564        rc = gfx_glyph_bmp_setpix(bmp, 7, 6, 0);
     565        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     566
     567        /* Check used rectangle got smaller */
     568
     569        gfx_glyph_bmp_find_used_rect(bmp, &rect);
     570        PCUT_ASSERT_INT_EQUALS(-2, rect.p0.x);
     571        PCUT_ASSERT_INT_EQUALS(-1, rect.p0.y);
     572        PCUT_ASSERT_INT_EQUALS(4, rect.p1.x);
     573        PCUT_ASSERT_INT_EQUALS(5, rect.p1.y);
    479574
    480575        gfx_glyph_bmp_close(bmp);
Note: See TracChangeset for help on using the changeset viewer.