Ignore:
File:
1 edited

Legend:

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

    rf2d4a46 ra0aeb8f  
    11/*
    2  * Copyright (c) 2022 Jiri Svoboda
     2 * Copyright (c) 2021 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    9797/** Print string using text characters in text mode.
    9898 *
     99 * @param font Font
    99100 * @param pos Position of top-left corner of text
    100  * @param fmt Formatting
     101 * @param color Text color
    101102 * @param str String
    102103 * @return EOK on success or an error code
    103104 */
    104 static errno_t gfx_puttext_textmode(gfx_coord2_t *pos, gfx_text_fmt_t *fmt,
    105     const char *str)
    106 {
    107         gfx_context_t *gc = fmt->font->typeface->gc;
     105static errno_t gfx_puttext_textmode(gfx_font_t *font, gfx_coord2_t *pos,
     106    gfx_color_t *color, const char *str)
     107{
     108        gfx_context_t *gc = font->typeface->gc;
    108109        gfx_bitmap_params_t params;
    109110        gfx_bitmap_t *bitmap;
    110111        gfx_bitmap_alloc_t alloc;
    111         gfx_coord_t width;
    112112        uint8_t attr;
    113113        pixelmap_t pmap;
    114114        gfx_coord_t x;
    115         gfx_coord_t rmargin;
    116115        pixel_t pixel;
    117116        char32_t c;
    118117        size_t off;
    119         bool ellipsis;
    120118        errno_t rc;
    121 
    122         width = str_width(str);
    123         if (fmt->abbreviate && width > fmt->width) {
    124                 ellipsis = true;
    125                 width = fmt->width;
    126                 if (width > 3)
    127                         rmargin = width - 3;
    128                 else
    129                         rmargin = width;
    130         } else {
    131                 ellipsis = false;
    132                 rmargin = width;
    133         }
    134119
    135120        /*
     
    138123         */
    139124
    140         gfx_color_get_ega(fmt->color, &attr);
     125        gfx_color_get_ega(color, &attr);
    141126
    142127        gfx_bitmap_params_init(&params);
    143128        params.rect.p0.x = 0;
    144129        params.rect.p0.y = 0;
    145         params.rect.p1.x = width;
     130        params.rect.p1.x = str_width(str);
    146131        params.rect.p1.y = 1;
    147132
     
    166151
    167152        off = 0;
    168         for (x = 0; x < rmargin; x++) {
     153        for (x = 0; x < params.rect.p1.x; x++) {
    169154                c = str_decode(str, &off, STR_NO_LIMIT);
    170155                pixel = PIXEL(attr,
     
    175160        }
    176161
    177         if (ellipsis) {
    178                 for (x = rmargin; x < params.rect.p1.x; x++) {
    179                         c = '.';
    180                         pixel = PIXEL(attr,
    181                             (c >> 16) & 0xff,
    182                             (c >> 8) & 0xff,
    183                             c & 0xff);
    184                         pixelmap_put_pixel(&pmap, x, 0, pixel);
    185                 }
    186         }
    187 
    188162        rc = gfx_bitmap_render(bitmap, NULL, pos);
    189163
     
    194168/** Get text starting position.
    195169 *
     170 * @param font Font
    196171 * @param pos Anchor position
    197172 * @param fmt Text formatting
     
    199174 * @param spos Place to store starting position
    200175 */
    201 void gfx_text_start_pos(gfx_coord2_t *pos, gfx_text_fmt_t *fmt,
    202     const char *str, gfx_coord2_t *spos)
     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)
    203178{
    204179        gfx_font_metrics_t fmetrics;
     
    209184        /* Adjust position for horizontal alignment */
    210185        if (fmt->halign != gfx_halign_left) {
    211                 /* Compute text width */
    212                 width = gfx_text_width(fmt->font, str);
    213                 if (fmt->abbreviate && width > fmt->width)
    214                         width = fmt->width;
    215 
     186                width = gfx_text_width(font, str);
    216187                switch (fmt->halign) {
    217188                case gfx_halign_center:
     
    227198
    228199        /* Adjust position for vertical alignment */
    229         gfx_font_get_metrics(fmt->font, &fmetrics);
     200        gfx_font_get_metrics(font, &fmetrics);
    230201
    231202        if (fmt->valign != gfx_valign_baseline) {
     
    248219/** Render text.
    249220 *
     221 * @param font Font
    250222 * @param pos Anchor position
    251223 * @param fmt Text formatting
     
    253225 * @return EOK on success or an error code
    254226 */
    255 errno_t gfx_puttext(gfx_coord2_t *pos, gfx_text_fmt_t *fmt, const char *str)
     227errno_t gfx_puttext(gfx_font_t *font, gfx_coord2_t *pos,
     228    gfx_text_fmt_t *fmt, const char *str)
    256229{
    257230        gfx_glyph_metrics_t gmetrics;
    258         gfx_font_metrics_t fmetrics;
    259231        size_t stradv;
    260232        const char *cp;
    261233        gfx_glyph_t *glyph;
    262234        gfx_coord2_t cpos;
    263         gfx_coord2_t spos;
    264         gfx_rect_t rect;
    265         gfx_coord_t width;
    266         gfx_coord_t rmargin;
    267         bool ellipsis;
    268235        errno_t rc;
    269236
    270         gfx_text_start_pos(pos, fmt, str, &spos);
     237        gfx_text_start_pos(font, pos, fmt, str, &cpos);
    271238
    272239        /* Text mode */
    273         if ((fmt->font->finfo->props.flags & gff_text_mode) != 0)
    274                 return gfx_puttext_textmode(&spos, fmt, str);
    275 
    276         rc = gfx_set_color(fmt->font->typeface->gc, fmt->color);
     240        if ((font->finfo->props.flags & gff_text_mode) != 0)
     241                return gfx_puttext_textmode(font, &cpos, fmt->color, str);
     242
     243        rc = gfx_set_color(font->typeface->gc, fmt->color);
    277244        if (rc != EOK)
    278245                return rc;
    279246
    280         width = gfx_text_width(fmt->font, str);
    281 
    282         if (fmt->abbreviate && width > fmt->width) {
    283                 /* Need to append ellipsis */
    284                 ellipsis = true;
    285                 rmargin = spos.x + fmt->width - gfx_text_width(fmt->font, "...");
    286         } else {
    287                 ellipsis = false;
    288                 rmargin = spos.x + width;
    289         }
    290 
    291         cpos = spos;
    292247        cp = str;
    293248        while (*cp != '\0') {
    294                 rc = gfx_font_search_glyph(fmt->font, cp, &glyph, &stradv);
     249                rc = gfx_font_search_glyph(font, cp, &glyph, &stradv);
    295250                if (rc != EOK) {
    296251                        ++cp;
     
    300255                gfx_glyph_get_metrics(glyph, &gmetrics);
    301256
    302                 /* Stop if we would run over the right margin */
    303                 if (fmt->abbreviate && cpos.x + gmetrics.advance > rmargin)
    304                         break;
    305 
    306257                rc = gfx_glyph_render(glyph, &cpos);
    307258                if (rc != EOK)
     
    312263        }
    313264
    314         /* Text underlining */
    315         if (fmt->underline) {
    316                 gfx_font_get_metrics(fmt->font, &fmetrics);
    317 
    318                 rect.p0.x = spos.x;
    319                 rect.p0.y = spos.y + fmetrics.underline_y0;
    320                 rect.p1.x = cpos.x;
    321                 rect.p1.y = spos.y + fmetrics.underline_y1;
    322 
    323                 rc = gfx_fill_rect(fmt->font->typeface->gc, &rect);
    324                 if (rc != EOK)
    325                         return rc;
    326         }
    327 
    328         /* Render ellipsis, if required */
    329         if (ellipsis) {
    330                 rc = gfx_font_search_glyph(fmt->font, ".", &glyph, &stradv);
    331                 if (rc != EOK)
    332                         return EOK;
    333 
    334                 gfx_glyph_get_metrics(glyph, &gmetrics);
    335 
    336                 rc = gfx_glyph_render(glyph, &cpos);
    337                 if (rc != EOK)
    338                         return rc;
    339 
    340                 cpos.x += gmetrics.advance;
    341 
    342                 rc = gfx_glyph_render(glyph, &cpos);
    343                 if (rc != EOK)
    344                         return rc;
    345 
    346                 cpos.x += gmetrics.advance;
    347 
    348                 rc = gfx_glyph_render(glyph, &cpos);
    349                 if (rc != EOK)
    350                         return rc;
    351         }
    352 
    353265        return EOK;
    354266}
     
    356268/** Find character position in string by X coordinate.
    357269 *
     270 * @param font Font
    358271 * @param pos Anchor position
    359272 * @param fmt Text formatting
     
    367280 *         offset of the following character.
    368281 */
    369 size_t gfx_text_find_pos(gfx_coord2_t *pos, gfx_text_fmt_t *fmt,
    370     const char *str, gfx_coord2_t *fpos)
     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)
    371284{
    372285        gfx_glyph_metrics_t gmetrics;
     
    379292        errno_t rc;
    380293
    381         gfx_text_start_pos(pos, fmt, str, &cpos);
     294        gfx_text_start_pos(font, pos, fmt, str, &cpos);
    382295
    383296        /* Text mode */
    384         if ((fmt->font->finfo->props.flags & gff_text_mode) != 0) {
     297        if ((font->finfo->props.flags & gff_text_mode) != 0) {
    385298                off = 0;
    386299                strsize = str_size(str);
     
    398311        off = 0;
    399312        while (*cp != '\0') {
    400                 rc = gfx_font_search_glyph(fmt->font, cp, &glyph, &stradv);
     313                rc = gfx_font_search_glyph(font, cp, &glyph, &stradv);
    401314                if (rc != EOK) {
    402315                        ++cp;
     
    424337 * to the same objects, respectively.
    425338 *
     339 * @param font Font
    426340 * @param pos Anchor position
    427341 * @param fmt Text formatting
     
    430344 * @param cfmt Place to store format for continuation
    431345 */
    432 void gfx_text_cont(gfx_coord2_t *pos, gfx_text_fmt_t *fmt, const char *str,
    433     gfx_coord2_t *cpos, gfx_text_fmt_t *cfmt)
     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)
    434349{
    435350        gfx_coord2_t spos;
     
    437352
    438353        /* Continuation should start where the current string ends */
    439         gfx_text_start_pos(pos, fmt, str, &spos);
    440         cpos->x = spos.x + gfx_text_width(fmt->font, str);
     354        gfx_text_start_pos(font, pos, fmt, str, &spos);
     355        cpos->x = spos.x + gfx_text_width(font, str);
    441356        cpos->y = spos.y;
    442357
     
    449364        tfmt.valign = gfx_valign_baseline;
    450365
    451         /* Remaining available width */
    452         tfmt.width = fmt->width - (cpos->x - spos.x);
    453 
    454366        *cfmt = tfmt;
    455367}
     
    457369/** Get text bounding rectangle.
    458370 *
     371 * @param font Font
    459372 * @param pos Anchor position
    460373 * @param fmt Text formatting
     
    462375 * @param rect Place to store bounding rectangle
    463376 */
    464 void gfx_text_rect(gfx_coord2_t *pos, gfx_text_fmt_t *fmt, const char *str,
    465     gfx_rect_t *rect)
     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)
    466379{
    467380        gfx_coord2_t spos;
    468         gfx_coord_t width;
    469 
    470         gfx_text_start_pos(pos, fmt, str, &spos);
    471         width = gfx_text_width(fmt->font, str);
    472         if (fmt->abbreviate && width > fmt->width)
    473                 width = fmt->width;
     381
     382        gfx_text_start_pos(font, pos, fmt, str, &spos);
    474383
    475384        rect->p0.x = spos.x;
    476         rect->p0.y = spos.y - fmt->font->metrics.ascent;
    477         rect->p1.x = spos.x + width;
    478         rect->p1.y = spos.y +  fmt->font->metrics.descent + 1;
     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;
    479388}
    480389
Note: See TracChangeset for help on using the changeset viewer.