Changeset c78a03d in mainline for uspace/lib/gfxfont/src


Ignore:
Timestamp:
2020-07-21T22:48:59Z (5 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5592c56
Parents:
703c743
Message:

Flesh out most of font, glyph and glyph bitmap implementation and tests

Location:
uspace/lib/gfxfont/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/gfxfont/src/font.c

    r703c743 rc78a03d  
    3434 */
    3535
     36#include <adt/list.h>
    3637#include <assert.h>
    3738#include <errno.h>
    3839#include <gfx/font.h>
     40#include <gfx/glyph.h>
    3941#include <mem.h>
    4042#include <stdlib.h>
    4143#include "../private/font.h"
     44#include "../private/glyph.h"
    4245
    4346/** Initialize font metrics structure.
     
    8386
    8487        font->metrics = *metrics;
     88        list_initialize(&font->glyphs);
    8589        *rfont = font;
    8690        return EOK;
     
    9397void gfx_font_destroy(gfx_font_t *font)
    9498{
     99        gfx_glyph_t *glyph;
     100
     101        glyph = gfx_font_first_glyph(font);
     102        while (glyph != NULL) {
     103                gfx_glyph_destroy(glyph);
     104                glyph = gfx_font_first_glyph(font);
     105        }
     106
    95107        free(font);
    96108}
     
    125137gfx_glyph_t *gfx_font_first_glyph(gfx_font_t *font)
    126138{
    127         return NULL;
     139        link_t *link;
     140
     141        link = list_first(&font->glyphs);
     142        if (link == NULL)
     143                return NULL;
     144
     145        return list_get_instance(link, gfx_glyph_t, lglyphs);
    128146}
    129147
     
    135153gfx_glyph_t *gfx_font_next_glyph(gfx_glyph_t *cur)
    136154{
    137         return NULL;
     155        link_t *link;
     156
     157        link = list_next(&cur->lglyphs, &cur->font->glyphs);
     158        if (link == NULL)
     159                return NULL;
     160
     161        return list_get_instance(link, gfx_glyph_t, lglyphs);
    138162}
    139163
     
    149173    gfx_glyph_t **rglyph, size_t *rsize)
    150174{
    151         return EOK;
     175        gfx_glyph_t *glyph;
     176        size_t msize;
     177
     178        glyph = gfx_font_first_glyph(font);
     179        while (glyph != NULL) {
     180                if (gfx_glyph_matches(glyph, str, &msize)) {
     181                        *rglyph = glyph;
     182                        *rsize = msize;
     183                        return EOK;
     184                }
     185
     186                glyph = gfx_font_next_glyph(glyph);
     187        }
     188
     189        return ENOENT;
    152190}
    153191
  • uspace/lib/gfxfont/src/glyph.c

    r703c743 rc78a03d  
    3939#include <mem.h>
    4040#include <stdlib.h>
     41#include <str.h>
     42#include "../private/font.h"
    4143#include "../private/glyph.h"
    4244
     
    8385
    8486        glyph->metrics = *metrics;
     87        list_append(&glyph->lglyphs, &glyph->font->glyphs);
     88        list_initialize(&glyph->patterns);
    8589        *rglyph = glyph;
    8690        return EOK;
     
    9397void gfx_glyph_destroy(gfx_glyph_t *glyph)
    9498{
     99        list_remove(&glyph->lglyphs);
    95100        free(glyph);
    96101}
     
    130135errno_t gfx_glyph_set_pattern(gfx_glyph_t *glyph, const char *pattern)
    131136{
     137        gfx_glyph_pattern_t *pat;
     138
     139        pat = gfx_glyph_first_pattern(glyph);
     140        while (pat != NULL) {
     141                if (str_cmp(pat->text, pattern) == 0) {
     142                        /* Already set */
     143                        return EOK;
     144                }
     145
     146                pat = gfx_glyph_next_pattern(pat);
     147        }
     148
     149        pat = calloc(1, sizeof(gfx_glyph_pattern_t));
     150        if (pat == NULL)
     151                return ENOMEM;
     152
     153        pat->glyph = glyph;
     154        pat->text = str_dup(pattern);
     155        if (pat->text == NULL) {
     156                free(pat);
     157                return ENOMEM;
     158        }
     159
     160        list_append(&pat->lpatterns, &glyph->patterns);
    132161        return EOK;
    133162}
     
    142171void gfx_glyph_clear_pattern(gfx_glyph_t *glyph, const char *pattern)
    143172{
    144 }
    145 
    146 /** Open glyph bitmap for editing.
    147  *
    148  * @param glyph Glyph
    149  * @param rbmp Place to store glyph bitmap
    150  * @return EOK on success, ENOMEM if out of memory
    151  */
    152 errno_t gfx_glyph_open_bmp(gfx_glyph_t *glyph, gfx_glyph_bmp_t **rbmp)
    153 {
    154         return EOK;
     173        gfx_glyph_pattern_t *pat;
     174
     175        pat = gfx_glyph_first_pattern(glyph);
     176        while (pat != NULL) {
     177                if (str_cmp(pat->text, pattern) == 0) {
     178                        list_remove(&pat->lpatterns);
     179                        free(pat->text);
     180                        free(pat);
     181                        return;
     182                }
     183
     184                pat = gfx_glyph_next_pattern(pat);
     185        }
     186}
     187
     188/** Determine if glyph maches the beginning of a string.
     189 *
     190 * @param glyph Glyph
     191 * @param str String
     192 * @param rsize Place to store number of bytes in the matching pattern
     193 * @return @c true iff glyph matches the beginning of the string
     194 */
     195bool gfx_glyph_matches(gfx_glyph_t *glyph, const char *str, size_t *rsize)
     196{
     197        gfx_glyph_pattern_t *pat;
     198
     199        pat = gfx_glyph_first_pattern(glyph);
     200        while (pat != NULL) {
     201                if (str_test_prefix(str, pat->text)) {
     202                        *rsize = str_size(pat->text);
     203                        return true;
     204                }
     205
     206                pat = gfx_glyph_next_pattern(pat);
     207        }
     208
     209        return false;
     210}
     211
     212/** Get first glyph pattern.
     213 *
     214 * @param glyph Glyph
     215 * @return First pattern or @c NULL if there are none
     216 */
     217gfx_glyph_pattern_t *gfx_glyph_first_pattern(gfx_glyph_t *glyph)
     218{
     219        link_t *link;
     220
     221        link = list_first(&glyph->patterns);
     222        if (link == NULL)
     223                return NULL;
     224
     225        return list_get_instance(link, gfx_glyph_pattern_t, lpatterns);
     226}
     227
     228/** Get next glyph pattern.
     229 *
     230 * @param cur Current pattern
     231 * @return Next pattern or @c NULL if there are none
     232 */
     233gfx_glyph_pattern_t *gfx_glyph_next_pattern(gfx_glyph_pattern_t *cur)
     234{
     235        link_t *link;
     236
     237        link = list_next(&cur->lpatterns, &cur->glyph->patterns);
     238        if (link == NULL)
     239                return NULL;
     240
     241        return list_get_instance(link, gfx_glyph_pattern_t, lpatterns);
     242}
     243
     244/** Return pattern string.
     245 *
     246 * @param pattern Pattern
     247 * @return Pattern string (owned by @a pattern)
     248 */
     249const char *gfx_glyph_pattern_str(gfx_glyph_pattern_t *pattern)
     250{
     251        return pattern->text;
    155252}
    156253
  • uspace/lib/gfxfont/src/glyph_bmp.c

    r703c743 rc78a03d  
    3535
    3636#include <errno.h>
     37#include <gfx/coord.h>
    3738#include <gfx/glyph_bmp.h>
    3839#include <stdlib.h>
    3940#include "../private/glyph_bmp.h"
     41
     42static errno_t gfx_glyph_bmp_extend(gfx_glyph_bmp_t *, gfx_coord2_t *);
     43
     44/** Open glyph bitmap for editing.
     45 *
     46 * @param glyph Glyph
     47 * @param rbmp Place to store glyph bitmap
     48 * @return EOK on success, ENOMEM if out of memory
     49 */
     50errno_t gfx_glyph_bmp_open(gfx_glyph_t *glyph, gfx_glyph_bmp_t **rbmp)
     51{
     52        gfx_glyph_bmp_t *bmp;
     53
     54        bmp = calloc(1, sizeof(gfx_glyph_bmp_t));
     55        if (bmp == NULL)
     56                return ENOMEM;
     57
     58        bmp->rect.p0.x = 0;
     59        bmp->rect.p0.y = 0;
     60        bmp->rect.p1.x = 0;
     61        bmp->rect.p1.y = 0;
     62        bmp->pixels = NULL;
     63
     64        bmp->glyph = glyph;
     65        *rbmp = bmp;
     66        return EOK;
     67}
    4068
    4169/** Save glyph bitmap.
     
    5583void gfx_glyph_bmp_close(gfx_glyph_bmp_t *bmp)
    5684{
     85        free(bmp->pixels);
     86        free(bmp);
    5787}
    5888
     
    6696int gfx_glyph_bmp_getpix(gfx_glyph_bmp_t *bmp, gfx_coord_t x, gfx_coord_t y)
    6797{
    68         return 0;
     98        gfx_coord2_t pos;
     99        size_t pitch;
     100
     101        pos.x = x;
     102        pos.y = y;
     103        if (!gfx_pix_inside_rect(&pos, &bmp->rect))
     104                return 0;
     105
     106        pitch = bmp->rect.p1.x - bmp->rect.p0.x;
     107        return bmp->pixels[(y - bmp->rect.p0.y) * pitch +
     108            (x - bmp->rect.p0.x)];
    69109}
    70110
     
    80120    gfx_coord_t y, int value)
    81121{
     122        gfx_coord2_t pos;
     123        size_t pitch;
     124        errno_t rc;
     125
     126        pos.x = x;
     127        pos.y = y;
     128        if (!gfx_pix_inside_rect(&pos, &bmp->rect)) {
     129                rc = gfx_glyph_bmp_extend(bmp, &pos);
     130                if (rc != EOK)
     131                        return rc;
     132        }
     133
     134        pitch = bmp->rect.p1.x - bmp->rect.p0.x;
     135        bmp->pixels[(y - bmp->rect.p0.y) * pitch +
     136            (x - bmp->rect.p0.x)] = value;
     137        return EOK;
     138}
     139
     140/** Extend glyph bitmap to cover a patricular pixel.
     141 *
     142 * @param bmp Glyph bitmap
     143 * @param pos Pixel position
     144 *
     145 * @return EOK on sucesss, ENOMEM if out of memory
     146 */
     147static errno_t gfx_glyph_bmp_extend(gfx_glyph_bmp_t *bmp, gfx_coord2_t *pos)
     148{
     149        gfx_rect_t prect;
     150        gfx_rect_t nrect;
     151        int *npixels;
     152        size_t npitch;
     153        size_t opitch;
     154        gfx_coord_t x, y;
     155
     156        /* Compute new rectangle enveloping current rectangle and new pixel */
     157        prect.p0 = *pos;
     158        prect.p1.x = prect.p0.x + 1;
     159        prect.p1.y = prect.p0.y + 1;
     160
     161        gfx_rect_envelope(&bmp->rect, &prect, &nrect);
     162
     163        /* Allocate new pixel array */
     164        npixels = calloc(sizeof(int), (nrect.p1.x - nrect.p0.x) *
     165            (nrect.p1.y - nrect.p0.y));
     166        if (npixels == NULL)
     167                return ENOMEM;
     168
     169        /* Transfer pixel data */
     170        opitch = bmp->rect.p1.x - bmp->rect.p0.x;
     171        npitch = nrect.p1.x - nrect.p0.x;
     172
     173        for (y = bmp->rect.p0.y; y < bmp->rect.p1.y; y++) {
     174                for (x = bmp->rect.p0.x; x < bmp->rect.p1.x; x++) {
     175                        npixels[(y - nrect.p0.y) * npitch + x - nrect.p0.x] =
     176                            bmp->pixels[(y - bmp->rect.p0.y) * opitch +
     177                                x - bmp->rect.p0.x];
     178                }
     179        }
     180
     181        /* Switch new and old data */
     182        free(bmp->pixels);
     183        bmp->pixels = npixels;
     184        bmp->rect = nrect;
     185
    82186        return EOK;
    83187}
Note: See TracChangeset for help on using the changeset viewer.