Ignore:
File:
1 edited

Legend:

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

    r17fac946 ra0aeb8f  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    110110        gfx_bitmap_t *bitmap;
    111111        gfx_bitmap_alloc_t alloc;
    112         uint16_t r, g, b;
     112        uint8_t attr;
    113113        pixelmap_t pmap;
    114114        gfx_coord_t x;
    115115        pixel_t pixel;
     116        char32_t c;
     117        size_t off;
    116118        errno_t rc;
    117119
     
    121123         */
    122124
    123         gfx_color_get_rgb_i16(color, &r, &g, &b);
    124 
    125         /*
    126          * We are setting the *background* color, the foreground color
    127          * will be set to its complement.
    128          */
    129         r = 0xff ^ (r >> 8);
    130         g = 0xff ^ (g >> 8);
    131         b = 0xff ^ (b >> 8);
     125        gfx_color_get_ega(color, &attr);
    132126
    133127        gfx_bitmap_params_init(&params);
     
    156150        pmap.data = alloc.pixels;
    157151
     152        off = 0;
    158153        for (x = 0; x < params.rect.p1.x; x++) {
    159                 pixel = PIXEL(str[x], r, g, b);
     154                c = str_decode(str, &off, STR_NO_LIMIT);
     155                pixel = PIXEL(attr,
     156                    (c >> 16) & 0xff,
     157                    (c >> 8) & 0xff,
     158                    c & 0xff);
    160159                pixelmap_put_pixel(&pmap, x, 0, pixel);
    161160        }
     
    167166}
    168167
     168/** Get text starting position.
     169 *
     170 * @param font Font
     171 * @param pos Anchor position
     172 * @param fmt Text formatting
     173 * @param str String
     174 * @param spos Place to store starting position
     175 */
     176void gfx_text_start_pos(gfx_font_t *font, gfx_coord2_t *pos,
     177    gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *spos)
     178{
     179        gfx_font_metrics_t fmetrics;
     180        gfx_coord_t width;
     181
     182        *spos = *pos;
     183
     184        /* Adjust position for horizontal alignment */
     185        if (fmt->halign != gfx_halign_left) {
     186                width = gfx_text_width(font, str);
     187                switch (fmt->halign) {
     188                case gfx_halign_center:
     189                        spos->x -= width / 2;
     190                        break;
     191                case gfx_halign_right:
     192                        spos->x -= width;
     193                        break;
     194                default:
     195                        break;
     196                }
     197        }
     198
     199        /* Adjust position for vertical alignment */
     200        gfx_font_get_metrics(font, &fmetrics);
     201
     202        if (fmt->valign != gfx_valign_baseline) {
     203                switch (fmt->valign) {
     204                case gfx_valign_top:
     205                        spos->y += fmetrics.ascent;
     206                        break;
     207                case gfx_valign_center:
     208                        spos->y += fmetrics.ascent / 2;
     209                        break;
     210                case gfx_valign_bottom:
     211                        spos->y -= fmetrics.descent + 1;
     212                        break;
     213                default:
     214                        break;
     215                }
     216        }
     217}
     218
    169219/** Render text.
    170220 *
     
    178228    gfx_text_fmt_t *fmt, const char *str)
    179229{
    180         gfx_font_metrics_t fmetrics;
    181230        gfx_glyph_metrics_t gmetrics;
    182231        size_t stradv;
     
    184233        gfx_glyph_t *glyph;
    185234        gfx_coord2_t cpos;
    186         gfx_coord_t width;
    187235        errno_t rc;
    188236
    189         cpos = *pos;
    190 
    191         /* Adjust position for horizontal alignment */
    192         if (fmt->halign != gfx_halign_left) {
    193                 width = gfx_text_width(font, str);
    194                 switch (fmt->halign) {
    195                 case gfx_halign_center:
    196                         cpos.x -= width / 2;
    197                         break;
    198                 case gfx_halign_right:
    199                         cpos.x -= width - 1;
    200                         break;
    201                 default:
    202                         break;
    203                 }
    204         }
    205 
    206         /* Adjust position for vertical alignment */
    207         gfx_font_get_metrics(font, &fmetrics);
    208 
    209         if (fmt->valign != gfx_valign_baseline) {
    210                 switch (fmt->valign) {
    211                 case gfx_valign_top:
    212                         cpos.y += fmetrics.ascent;
    213                         break;
    214                 case gfx_valign_center:
    215                         cpos.y += fmetrics.ascent / 2;
    216                         break;
    217                 case gfx_valign_bottom:
    218                         cpos.y -= fmetrics.descent;
    219                         break;
    220                 default:
    221                         break;
    222                 }
    223         }
     237        gfx_text_start_pos(font, pos, fmt, str, &cpos);
    224238
    225239        /* Text mode */
     
    252266}
    253267
     268/** Find character position in string by X coordinate.
     269 *
     270 * @param font Font
     271 * @param pos Anchor position
     272 * @param fmt Text formatting
     273 * @param str String
     274 * @param fpos Position for which we need to find offset
     275 *
     276 * @return Byte offset in @a str of character corresponding to position
     277 *         @a fpos. Note that the position is rounded, that is,
     278 *         if it is before the center of character A, it will return
     279 *         offset of A, if it is after the center of A, it will return
     280 *         offset of the following character.
     281 */
     282size_t gfx_text_find_pos(gfx_font_t *font, gfx_coord2_t *pos,
     283    gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *fpos)
     284{
     285        gfx_glyph_metrics_t gmetrics;
     286        size_t stradv;
     287        const char *cp;
     288        gfx_glyph_t *glyph;
     289        gfx_coord2_t cpos;
     290        size_t off;
     291        size_t strsize;
     292        errno_t rc;
     293
     294        gfx_text_start_pos(font, pos, fmt, str, &cpos);
     295
     296        /* Text mode */
     297        if ((font->finfo->props.flags & gff_text_mode) != 0) {
     298                off = 0;
     299                strsize = str_size(str);
     300                while (off < strsize) {
     301                        if (fpos->x <= cpos.x)
     302                                return off;
     303                        (void) str_decode(str, &off, strsize);
     304                        cpos.x++;
     305                }
     306
     307                return off;
     308        }
     309
     310        cp = str;
     311        off = 0;
     312        while (*cp != '\0') {
     313                rc = gfx_font_search_glyph(font, cp, &glyph, &stradv);
     314                if (rc != EOK) {
     315                        ++cp;
     316                        continue;
     317                }
     318
     319                gfx_glyph_get_metrics(glyph, &gmetrics);
     320
     321                if (fpos->x < cpos.x + gmetrics.advance / 2)
     322                        return off;
     323
     324                cp += stradv;
     325                off += stradv;
     326                cpos.x += gmetrics.advance;
     327        }
     328
     329        return off;
     330}
     331
     332/** Get text continuation parameters.
     333 *
     334 * Return the anchor position and format needed to continue printing
     335 * text after the specified string. It is allowed for the sources
     336 * (@a pos, @a fmt) and destinations (@a cpos, @a cfmt) to point
     337 * to the same objects, respectively.
     338 *
     339 * @param font Font
     340 * @param pos Anchor position
     341 * @param fmt Text formatting
     342 * @param str String
     343 * @param cpos Place to store anchor position for continuation
     344 * @param cfmt Place to store format for continuation
     345 */
     346void gfx_text_cont(gfx_font_t *font, gfx_coord2_t *pos,
     347    gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *cpos,
     348    gfx_text_fmt_t *cfmt)
     349{
     350        gfx_coord2_t spos;
     351        gfx_text_fmt_t tfmt;
     352
     353        /* Continuation should start where the current string ends */
     354        gfx_text_start_pos(font, pos, fmt, str, &spos);
     355        cpos->x = spos.x + gfx_text_width(font, str);
     356        cpos->y = spos.y;
     357
     358        /*
     359         * Formatting is the same, except the text should be aligned
     360         * so that it starts at the anchor point.
     361         */
     362        tfmt = *fmt;
     363        tfmt.halign = gfx_halign_left;
     364        tfmt.valign = gfx_valign_baseline;
     365
     366        *cfmt = tfmt;
     367}
     368
     369/** Get text bounding rectangle.
     370 *
     371 * @param font Font
     372 * @param pos Anchor position
     373 * @param fmt Text formatting
     374 * @param str String
     375 * @param rect Place to store bounding rectangle
     376 */
     377void gfx_text_rect(gfx_font_t *font, gfx_coord2_t *pos,
     378    gfx_text_fmt_t *fmt, const char *str, gfx_rect_t *rect)
     379{
     380        gfx_coord2_t spos;
     381
     382        gfx_text_start_pos(font, pos, fmt, str, &spos);
     383
     384        rect->p0.x = spos.x;
     385        rect->p0.y = spos.y - font->metrics.ascent;
     386        rect->p1.x = spos.x + gfx_text_width(font, str);
     387        rect->p1.y = spos.y + font->metrics.descent + 1;
     388}
     389
    254390/** @}
    255391 */
Note: See TracChangeset for help on using the changeset viewer.