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


Ignore:
Timestamp:
2021-10-24T08:28:43Z (3 years ago)
Author:
GitHub <noreply@…>
Children:
f628215
Parents:
2ce943a (diff), cd981f2a (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
git-author:
Erik Kučák <35500848+Riko196@…> (2021-10-24 08:28:43)
git-committer:
GitHub <noreply@…> (2021-10-24 08:28:43)
Message:

Merge branch 'HelenOS:master' into master

File:
1 edited

Legend:

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

    r2ce943a r8a9a41e  
    3838#include <gfx/context.h>
    3939#include <gfx/render.h>
     40#include <gfx/text.h>
    4041#include <ui/paint.h>
     42#include <stdlib.h>
     43#include <str.h>
    4144#include "../private/resource.h"
     45
     46/** Single box characters */
     47static ui_box_chars_t single_box_chars = {
     48        {
     49                { "\u250c", "\u2500", "\u2510" },
     50                { "\u2502", " ",      "\u2502" },
     51                { "\u2514", "\u2500", "\u2518" }
     52        }
     53};
     54
     55/** Double box characters */
     56static ui_box_chars_t double_box_chars = {
     57        {
     58                { "\u2554", "\u2550", "\u2557" },
     59                { "\u2551", " ",      "\u2551" },
     60                { "\u255a", "\u2550", "\u255d" }
     61        }
     62};
     63
     64/** Single horizontal brace characters */
     65static ui_brace_chars_t single_hbrace_chars = {
     66        .start = "\u251c",
     67        .middle = "\u2500",
     68        .end = "\u2524"
     69};
     70
     71/** Double horizontal brace characters */
     72static ui_brace_chars_t double_hbrace_chars = {
     73        .start = "\u2560",
     74        .middle = "\u2550",
     75        .end = "\u2563"
     76};
    4277
    4378/** Paint bevel.
     
    4984 * @param thickness Bevel thickness in pixels
    5085 * @param inside Place to store rectangle of the interior or @c NULL
    51  * @reutrn EOK on success or an error code
     86 * @return EOK on success or an error code
    5287 */
    5388errno_t ui_paint_bevel(gfx_context_t *gc, gfx_rect_t *rect,
     
    107142        }
    108143
    109         if (inside != NULL) {
    110                 inside->p0.x = rect->p0.x + thickness;
    111                 inside->p0.y = rect->p0.y + thickness;
    112                 inside->p1.x = rect->p1.x - thickness;
    113                 inside->p1.y = rect->p1.y - thickness;
    114         }
     144        if (inside != NULL)
     145                ui_paint_get_bevel_inside(gc, rect, thickness, inside);
    115146
    116147        return EOK;
    117148error:
    118149        return rc;
     150}
     151
     152/** Get bevel interior rectangle.
     153 *
     154 * Get the bevel interior rectangle without painting it.
     155 *
     156 * @param gc Graphic context
     157 * @param rect Rectangle to paint into
     158 * @param thickness Bevel thickness in pixels
     159 * @param inside Place to store rectangle of the interior
     160 */
     161void ui_paint_get_bevel_inside(gfx_context_t *gc, gfx_rect_t *rect,
     162    gfx_coord_t thickness, gfx_rect_t *inside)
     163{
     164        inside->p0.x = rect->p0.x + thickness;
     165        inside->p0.y = rect->p0.y + thickness;
     166        inside->p1.x = rect->p1.x - thickness;
     167        inside->p1.y = rect->p1.y - thickness;
    119168}
    120169
     
    147196error:
    148197        return rc;
     198}
     199
     200/** Get inset frame interior rectangle.
     201 *
     202 * This allows one to get the interior rectangle without actually painting
     203 * the inset frame.
     204 *
     205 * @param resource UI resource
     206 * @param rect Rectangle to paint onto
     207 * @param inside Place to store inside rectangle or @c NULL
     208 */
     209void ui_paint_get_inset_frame_inside(ui_resource_t *resource, gfx_rect_t *rect,
     210    gfx_rect_t *inside)
     211{
     212        ui_paint_get_bevel_inside(resource->gc, rect, 2, inside);
    149213}
    150214
     
    295359}
    296360
     361/** Paint a text box.
     362 *
     363 * @param resource UI resource
     364 * @param rect Rectangle inside which to paint the box
     365 * @param style Box style
     366 * @param color Color
     367 * @return EOK on success or an error code
     368 */
     369errno_t ui_paint_text_box(ui_resource_t *resource, gfx_rect_t *rect,
     370    ui_box_style_t style, gfx_color_t *color)
     371{
     372        errno_t rc;
     373        gfx_text_fmt_t fmt;
     374        gfx_rect_t srect;
     375        gfx_coord2_t pos;
     376        gfx_coord2_t dim;
     377        size_t bufsz;
     378        size_t off;
     379        int i;
     380        gfx_coord_t y;
     381        char *str = NULL;
     382        ui_box_chars_t *boxc = NULL;
     383
     384        gfx_rect_points_sort(rect, &srect);
     385        gfx_rect_dims(&srect, &dim);
     386
     387        /* Is rectangle large enough to hold box? */
     388        if (dim.x < 2 || dim.y < 2)
     389                return EOK;
     390
     391        switch (style) {
     392        case ui_box_single:
     393                boxc = &single_box_chars;
     394                break;
     395        case ui_box_double:
     396                boxc = &double_box_chars;
     397                break;
     398        }
     399
     400        if (boxc == NULL)
     401                return EINVAL;
     402
     403        gfx_text_fmt_init(&fmt);
     404        fmt.color = color;
     405
     406        bufsz = str_size(boxc->c[0][0]) +
     407            str_size(boxc->c[0][1]) * (dim.x - 2) +
     408            str_size(boxc->c[0][2]) + 1;
     409
     410        str = malloc(bufsz);
     411        if (str == NULL)
     412                return ENOMEM;
     413
     414        /* Top edge and corners */
     415
     416        str_cpy(str, bufsz, boxc->c[0][0]);
     417        off = str_size(boxc->c[0][0]);
     418
     419        for (i = 1; i < dim.x - 1; i++) {
     420                str_cpy(str + off, bufsz - off, boxc->c[0][1]);
     421                off += str_size(boxc->c[0][1]);
     422        }
     423
     424        str_cpy(str + off, bufsz - off, boxc->c[0][2]);
     425        off += str_size(boxc->c[0][2]);
     426        str[off] = '\0';
     427
     428        pos = rect->p0;
     429        rc = gfx_puttext(resource->font, &pos, &fmt, str);
     430        if (rc != EOK)
     431                goto error;
     432
     433        /* Vertical edges */
     434        for (y = rect->p0.y + 1; y < rect->p1.y - 1; y++) {
     435                pos.y = y;
     436
     437                pos.x = rect->p0.x;
     438                rc = gfx_puttext(resource->font, &pos, &fmt,
     439                    boxc->c[1][0]);
     440                if (rc != EOK)
     441                        goto error;
     442
     443                pos.x = rect->p1.x - 1;
     444                rc = gfx_puttext(resource->font, &pos, &fmt,
     445                    boxc->c[1][2]);
     446                if (rc != EOK)
     447                        goto error;
     448        }
     449
     450        /* Bottom edge and corners */
     451
     452        str_cpy(str, bufsz, boxc->c[2][0]);
     453        off = str_size(boxc->c[2][0]);
     454
     455        for (i = 1; i < dim.x - 1; i++) {
     456                str_cpy(str + off, bufsz - off, boxc->c[2][1]);
     457                off += str_size(boxc->c[2][1]);
     458        }
     459
     460        str_cpy(str + off, bufsz - off, boxc->c[2][2]);
     461        off += str_size(boxc->c[2][2]);
     462        str[off] = '\0';
     463
     464        pos.x = rect->p0.x;
     465        pos.y = rect->p1.y - 1;
     466        rc = gfx_puttext(resource->font, &pos, &fmt, str);
     467        if (rc != EOK)
     468                goto error;
     469
     470        free(str);
     471        return EOK;
     472error:
     473        if (str != NULL)
     474                free(str);
     475        return rc;
     476}
     477
     478/** Paint a text horizontal brace.
     479 *
     480 * @param resource UI resource
     481 * @param rect Rectangle inside which to paint the brace (height should
     482 *             be 1).
     483 * @param style Box style
     484 * @param color Color
     485 * @return EOK on success or an error code
     486 */
     487errno_t ui_paint_text_hbrace(ui_resource_t *resource, gfx_rect_t *rect,
     488    ui_box_style_t style, gfx_color_t *color)
     489{
     490        errno_t rc;
     491        gfx_text_fmt_t fmt;
     492        gfx_rect_t srect;
     493        gfx_coord2_t pos;
     494        gfx_coord2_t dim;
     495        size_t bufsz;
     496        size_t off;
     497        int i;
     498        char *str = NULL;
     499        ui_brace_chars_t *hbc = NULL;
     500
     501        gfx_rect_points_sort(rect, &srect);
     502        gfx_rect_dims(&srect, &dim);
     503
     504        /* Is rectangle large enough to hold brace? */
     505        if (dim.x < 2 || dim.y < 1)
     506                return EOK;
     507
     508        switch (style) {
     509        case ui_box_single:
     510                hbc = &single_hbrace_chars;
     511                break;
     512        case ui_box_double:
     513                hbc = &double_hbrace_chars;
     514                break;
     515        }
     516
     517        if (hbc == NULL)
     518                return EINVAL;
     519
     520        gfx_text_fmt_init(&fmt);
     521        fmt.color = color;
     522
     523        bufsz = str_size(hbc->start) +
     524            str_size(hbc->middle) * (dim.x - 2) +
     525            str_size(hbc->end) + 1;
     526
     527        str = malloc(bufsz);
     528        if (str == NULL)
     529                return ENOMEM;
     530
     531        str_cpy(str, bufsz, hbc->start);
     532        off = str_size(hbc->start);
     533
     534        for (i = 1; i < dim.x - 1; i++) {
     535                str_cpy(str + off, bufsz - off, hbc->middle);
     536                off += str_size(hbc->middle);
     537        }
     538
     539        str_cpy(str + off, bufsz - off, hbc->end);
     540        off += str_size(hbc->end);
     541        str[off] = '\0';
     542
     543        pos = rect->p0;
     544        rc = gfx_puttext(resource->font, &pos, &fmt, str);
     545        if (rc != EOK)
     546                goto error;
     547
     548        free(str);
     549        return EOK;
     550error:
     551        if (str != NULL)
     552                free(str);
     553        return rc;
     554}
     555
    297556/** @}
    298557 */
Note: See TracChangeset for help on using the changeset viewer.