Changeset d63623f in mainline for uspace/lib/gfxfont/src/text.c


Ignore:
Timestamp:
2021-07-16T17:45:12Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
4afb6c9
Parents:
61bf9dd9
Message:

Seeking in entry text using mouse

File:
1 edited

Legend:

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

    r61bf9dd9 rd63623f  
    11/*
    2  * Copyright (c) 2020 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    167167}
    168168
    169 /** Render text.
     169/** Get text starting position.
    170170 *
    171171 * @param font Font
     
    173173 * @param fmt Text formatting
    174174 * @param str String
     175 * @param spos Place to store starting position
     176 * @return EOK on success or an error code
     177 */
     178void gfx_text_start_pos(gfx_font_t *font, gfx_coord2_t *pos,
     179    gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *spos)
     180{
     181        gfx_font_metrics_t fmetrics;
     182        gfx_coord2_t cpos;
     183        gfx_coord_t width;
     184
     185        *spos = *pos;
     186
     187        /* Adjust position for horizontal alignment */
     188        if (fmt->halign != gfx_halign_left) {
     189                width = gfx_text_width(font, str);
     190                switch (fmt->halign) {
     191                case gfx_halign_center:
     192                        spos->x -= width / 2;
     193                        break;
     194                case gfx_halign_right:
     195                        spos->x -= width - 1;
     196                        break;
     197                default:
     198                        break;
     199                }
     200        }
     201
     202        /* Adjust position for vertical alignment */
     203        gfx_font_get_metrics(font, &fmetrics);
     204
     205        if (fmt->valign != gfx_valign_baseline) {
     206                switch (fmt->valign) {
     207                case gfx_valign_top:
     208                        spos->y += fmetrics.ascent;
     209                        break;
     210                case gfx_valign_center:
     211                        spos->y += fmetrics.ascent / 2;
     212                        break;
     213                case gfx_valign_bottom:
     214                        cpos.y -= fmetrics.descent;
     215                        break;
     216                default:
     217                        break;
     218                }
     219        }
     220}
     221
     222/** Render text.
     223 *
     224 * @param font Font
     225 * @param pos Anchor position
     226 * @param fmt Text formatting
     227 * @param str String
    175228 * @return EOK on success or an error code
    176229 */
     
    178231    gfx_text_fmt_t *fmt, const char *str)
    179232{
    180         gfx_font_metrics_t fmetrics;
    181233        gfx_glyph_metrics_t gmetrics;
    182234        size_t stradv;
     
    184236        gfx_glyph_t *glyph;
    185237        gfx_coord2_t cpos;
    186         gfx_coord_t width;
    187238        errno_t rc;
    188239
    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         }
     240        gfx_text_start_pos(font, pos, fmt, str, &cpos);
    224241
    225242        /* Text mode */
     
    252269}
    253270
     271/** Find character position in string by X coordinate.
     272 *
     273 * @param font Font
     274 * @param pos Anchor position
     275 * @param fmt Text formatting
     276 * @param str String
     277 * @param fpos Position for which we need to find offset
     278 *
     279 * @return Byte offset in @a str of character corresponding to position
     280 *         @a fpos. Note that the position is rounded, that is,
     281 *         if it is before the center of character A, it will return
     282 *         offset of A, if it is after the center of A, it will return
     283 *         offset of the following character.
     284 */
     285size_t gfx_text_find_pos(gfx_font_t *font, gfx_coord2_t *pos,
     286    gfx_text_fmt_t *fmt, const char *str, gfx_coord2_t *fpos)
     287{
     288        gfx_glyph_metrics_t gmetrics;
     289        size_t stradv;
     290        const char *cp;
     291        gfx_glyph_t *glyph;
     292        gfx_coord2_t cpos;
     293        size_t off;
     294        size_t strsize;
     295        errno_t rc;
     296
     297        gfx_text_start_pos(font, pos, fmt, str, &cpos);
     298
     299        /* Text mode */
     300        if ((font->finfo->props.flags & gff_text_mode) != 0) {
     301                off = 0;
     302                strsize = str_size(str);
     303                while (off < strsize) {
     304                        if (fpos->x <= cpos.x)
     305                                return off;
     306                        (void) str_decode(str, &off, strsize);
     307                        cpos.x++;
     308                }
     309
     310                return off;
     311        }
     312
     313        cp = str;
     314        off = 0;
     315        while (*cp != '\0') {
     316                rc = gfx_font_search_glyph(font, cp, &glyph, &stradv);
     317                if (rc != EOK) {
     318                        ++cp;
     319                        continue;
     320                }
     321
     322                gfx_glyph_get_metrics(glyph, &gmetrics);
     323
     324                if (fpos->x < cpos.x + gmetrics.advance / 2)
     325                        return off;
     326
     327                cp += stradv;
     328                off += stradv;
     329                cpos.x += gmetrics.advance;
     330        }
     331
     332        return off;
     333}
     334
    254335/** @}
    255336 */
Note: See TracChangeset for help on using the changeset viewer.