Changeset ca2680d in mainline for uspace/lib/ui/src/paint.c


Ignore:
Timestamp:
2022-03-07T21:07:02Z (3 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
master, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
96c6a00
Parents:
4583015
Message:

Rendering UI text with highlighted accelerators

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/ui/src/paint.c

    r4583015 rca2680d  
    554554}
    555555
     556/** Initialize UI text formatting structure.
     557 *
     558 * UI text formatting structure must always be initialized using this function
     559 * first.
     560 *
     561 * @param fmt UI text formatting structure
     562 */
     563void ui_text_fmt_init(ui_text_fmt_t *fmt)
     564{
     565        memset(fmt, 0, sizeof(ui_text_fmt_t));
     566}
     567
     568/** Process text with '~' markup.
     569 *
     570 * Parse text with tilde markup into a list of strings. @a *rbuf is set
     571 * to point to a newly allocated buffer containing consecutive null-terminated
     572 * strings.
     573 *
     574 * Each part between two '~' becomes one string. '~~' is translated into
     575 * a literal '~' character. @a *endptr is set to point to the first character
     576 * beyond the end of the list.
     577 *
     578 * @param str String with tilde markup
     579 * @param rbuf Place to store pointer to newly allocated buffer.
     580 * @param endptr Place to store end pointer (just after last character)
     581 * @return EOK on success or an error code
     582 */
     583static int ui_text_process(const char *str, char **rbuf, char **endptr)
     584{
     585        const char *sp;
     586        char *dp;
     587        char *buf;
     588
     589        buf = malloc(str_size(str) + 1);
     590        if (buf == NULL)
     591                return ENOMEM;
     592
     593        /* Break down string into list of (non)highlighted parts */
     594        sp = str;
     595        dp = buf;
     596        while (*sp != '\0') {
     597                if (*sp == '~') {
     598                        if (sp[1] == '~') {
     599                                sp += 2;
     600                                *dp++ = '~';
     601                        } else {
     602                                ++sp;
     603                                *dp++ = '\0';
     604                        }
     605                } else {
     606                        *dp++ = *sp++;
     607                }
     608        }
     609
     610        *dp++ = '\0';
     611        *rbuf = buf;
     612        *endptr = dp;
     613
     614        return EOK;
     615}
     616
     617/** Compute UI text width.
     618 *
     619 * @param font Font
     620 * @param str String
     621 * @return Text width
     622 */
     623gfx_coord_t ui_text_width(gfx_font_t *font, const char *str)
     624{
     625        gfx_coord_t w;
     626        gfx_coord_t tw;
     627        const char *sp;
     628
     629        /* Text including tildes */
     630        w = gfx_text_width(font, str);
     631        tw = gfx_text_width(font, "~");
     632
     633        /* Subtract width of singular tildes */
     634        sp = str;
     635        while (*sp != '\0') {
     636                if (*sp == '~' && sp[1] != '~')
     637                        w -= tw;
     638                ++sp;
     639        }
     640
     641        return w;
     642}
     643
     644/** Paint text (with highlighting markup).
     645 *
     646 * Paint some text with highlighted sections enclosed with tilde characters
     647 * ('~'). A literal tilde can be printed with "~~". Text can be highlighted
     648 * with an underline or different color, based on display capabilities.
     649 *
     650 * @param pos Anchor position
     651 * @param fmt Text formatting
     652 * @param str String containing '~' markup
     653 *
     654 * @return EOK on success or an error code
     655 */
     656errno_t ui_paint_text(gfx_coord2_t *pos, ui_text_fmt_t *fmt, const char *str)
     657{
     658        gfx_coord2_t tpos;
     659        gfx_text_fmt_t tfmt;
     660        char *buf;
     661        char *endptr;
     662        const char *sp;
     663        errno_t rc;
     664
     665        /* Break down string into list of (non)highlighted parts */
     666        rc = ui_text_process(str, &buf, &endptr);
     667        if (rc != EOK)
     668                return rc;
     669
     670        gfx_text_fmt_init(&tfmt);
     671        tfmt.font = fmt->font;
     672        tfmt.color = fmt->color;
     673        tfmt.halign = fmt->halign;
     674        tfmt.justify_width = fmt->justify_width;
     675        tfmt.valign = fmt->valign;
     676        tfmt.underline = false;
     677
     678        tpos = *pos;
     679        sp = buf;
     680        while (sp != endptr) {
     681                /* Print the current string */
     682                rc = gfx_puttext(&tpos, &tfmt, sp);
     683                if (rc != EOK)
     684                        goto error;
     685
     686                gfx_text_cont(&tpos, &tfmt, sp, &tpos, &tfmt);
     687                tfmt.underline = !tfmt.underline;
     688                tfmt.color = tfmt.underline ? fmt->hgl_color : fmt->color;
     689
     690                /* Skip to the next string */
     691                while (*sp != '\0')
     692                        ++sp;
     693                ++sp;
     694        }
     695
     696        free(buf);
     697        return EOK;
     698error:
     699        free(buf);
     700        return rc;
     701}
     702
    556703/** @}
    557704 */
Note: See TracChangeset for help on using the changeset viewer.