Changeset 66a2becf in mainline


Ignore:
Timestamp:
2020-11-11T18:05:01Z (4 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
b93ec7c0
Parents:
d942ca4
Message:

Application area GC / port font editor

Font editor and other 'non-GUI' applications typically assume that
0,0 is the top left of the 'screen'/application area. We provide
a special GC that meets this requirement.

Location:
uspace
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/fontedit/fontedit.c

    rd942ca4 r66a2becf  
    3333 */
    3434
    35 #include <canvas.h>
    36 #include <draw/surface.h>
    3735#include <fibril.h>
    38 #include <guigfx/canvas.h>
    3936#include <gfx/color.h>
    4037#include <gfx/font.h>
     
    4744#include <stdlib.h>
    4845#include <str.h>
    49 #include <task.h>
    50 #include <window.h>
     46#include <ui/ui.h>
     47#include <ui/wdecor.h>
     48#include <ui/window.h>
    5149#include "fontedit.h"
    5250
     
    5856
    5957static errno_t font_edit_paint(font_edit_t *);
     58
     59static void font_edit_close_event(ui_window_t *, void *);
     60static void font_edit_kbd_event(ui_window_t *, void *, kbd_event_t *);
     61static void font_edit_pos_event(ui_window_t *, void *, pos_event_t *);
     62
     63static ui_window_cb_t font_edit_window_cb = {
     64        .close = font_edit_close_event,
     65        .kbd = font_edit_kbd_event,
     66        .pos = font_edit_pos_event
     67};
    6068
    6169/** Clear screen.
     
    159167}
    160168
     169/** Handle font editor close event.
     170 *
     171 * @param window Window
     172 * @param arg Argument (font_edit_t *)
     173 */
     174static void font_edit_close_event(ui_window_t *window, void *arg)
     175{
     176        font_edit_t *fedit = (font_edit_t *) arg;
     177
     178        ui_quit(fedit->ui);
     179}
     180
    161181/** Handle font editor position event.
    162182 *
    163  * @param widget Canvas widget
    164  * @param data Position event
    165  */
    166 static void font_edit_pos_event(widget_t *widget, void *data)
    167 {
    168         pos_event_t *event = (pos_event_t *) data;
    169         font_edit_t *fedit;
     183 * @param window Window
     184 * @param arg Argument (font_edit_t *)
     185 * @param event Position event
     186 */
     187static void font_edit_pos_event(ui_window_t *window, void *arg,
     188    pos_event_t *event)
     189{
     190        font_edit_t *fedit = (font_edit_t *) arg;
     191        gfx_coord2_t pos;
     192        gfx_rect_t rect;
    170193        int x, y;
    171194
    172         fedit = (font_edit_t *) widget_get_data(widget);
    173 
    174         if (event->type == POS_PRESS) {
    175                 x = gfx_coord_div_rneg((int)event->hpos - glyph_orig_x,
    176                     glyph_scale);
    177                 y = gfx_coord_div_rneg((int)event->vpos - glyph_orig_y,
    178                     glyph_scale);
    179 
    180                 printf("x=%d y=%d\n", x, y);
    181                 gfx_glyph_bmp_setpix(fedit->gbmp, x, y, fedit->pen_color);
    182                 font_edit_paint(fedit);
    183         }
     195        ui_window_get_app_rect(window, &rect);
     196
     197        pos.x = event->hpos;
     198        pos.y = event->vpos;
     199
     200        if (event->type != POS_PRESS)
     201                return;
     202
     203        if (!gfx_pix_inside_rect(&pos, &rect))
     204                return;
     205
     206        x = gfx_coord_div_rneg(pos.x - glyph_orig_x -
     207            rect.p0.x, glyph_scale);
     208        y = gfx_coord_div_rneg(pos.y - glyph_orig_y -
     209            rect.p0.y, glyph_scale);
     210
     211        printf("x=%d y=%d\n", x, y);
     212        gfx_glyph_bmp_setpix(fedit->gbmp, x, y, fedit->pen_color);
     213        font_edit_paint(fedit);
    184214}
    185215
     
    371401/** Handle font editor keyboard event.
    372402 *
    373  * @param widget Canvas widget
    374  * @param data Position event
    375  */
    376 static void font_edit_kbd_event(widget_t *widget, void *data)
    377 {
    378         kbd_event_t *event = (kbd_event_t *) data;
    379         font_edit_t *fedit;
    380 
    381         fedit = (font_edit_t *) widget_get_data(widget);
     403 * @param window Window
     404 * @param arg Argument (font_edit_t *)
     405 * @param event Keyboard event
     406 */
     407static void font_edit_kbd_event(ui_window_t *window, void *arg,
     408    kbd_event_t *event)
     409{
     410        font_edit_t *fedit = (font_edit_t *) arg;
    382411
    383412        if (event->type != KEY_PRESS)
     
    440469static errno_t font_edit_paint_preview(font_edit_t *fedit)
    441470{
     471        gfx_color_t *color;
    442472        errno_t rc;
     473
     474        rc = gfx_color_new_rgb_i16(0xffff, 0xffff, 0xffff, &color);
     475        if (rc != EOK)
     476                return rc;
     477
     478        rc = gfx_set_color(fedit->gc, color);
     479        if (rc != EOK)
     480                goto error;
    443481
    444482        rc = font_edit_paint_preview_str(fedit, 20, 20,
    445483            "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
    446484        if (rc != EOK)
    447                 return rc;
     485                goto error;
    448486
    449487        rc = font_edit_paint_preview_str(fedit, 20, 40,
    450488            "THE QUICK BROWN FOX JUMPS OVER THE LAZY DOG");
    451489        if (rc != EOK)
    452                 return rc;
     490                goto error;
    453491
    454492        rc = font_edit_paint_preview_str(fedit, 20, 60,
    455493            "abcdefghijklmnopqrstuvwxyz");
    456494        if (rc != EOK)
    457                 return rc;
     495                goto error;
    458496
    459497        rc = font_edit_paint_preview_str(fedit, 20, 80,
    460498            "the quick brown fox jumps over the lazy dog");
    461499        if (rc != EOK)
    462                 return rc;
     500                goto error;
    463501
    464502        rc = font_edit_paint_preview_str(fedit, 20, 100,
    465503            "0123456789,./<>?;'\\:\"|[]{}`~!@#$%^&*()-_=+");
    466504        if (rc != EOK)
    467                 return rc;
     505                goto error;
    468506
    469507        return EOK;
     508error:
     509        gfx_color_delete(color);
     510        return rc;
    470511}
    471512
     
    620661/** Create font editor.
    621662 *
    622  * @param display_svc Display service
     663 * @param display_spec Display specifier
    623664 * @param fname Font file to open or @c NULL to create new font
    624665 * @param rfedit Place to store pointer to new font editor
    625666 * @return EOK on success or an error code
    626667 */
    627 static errno_t font_edit_create(const char *display_svc, const char *fname,
     668static errno_t font_edit_create(const char *display_spec, const char *fname,
    628669    font_edit_t **rfedit)
    629670{
    630         canvas_gc_t *cgc = NULL;
    631         window_t *window = NULL;
    632         pixel_t *pixbuf = NULL;
    633         surface_t *surface = NULL;
    634         canvas_t *canvas = NULL;
     671        ui_t *ui = NULL;
     672        ui_wnd_params_t params;
     673        gfx_rect_t rect;
     674        gfx_rect_t wrect;
     675        gfx_coord2_t off;
     676        ui_window_t *window = NULL;
     677        gfx_context_t *gc = NULL;
    635678        font_edit_t *fedit = NULL;
    636679        gfx_typeface_t *tface = NULL;
     
    643686        gfx_glyph_bmp_t *bmp;
    644687        gfx_coord_t vw, vh;
    645         gfx_context_t *gc;
    646688        errno_t rc;
    647689
     
    652694        }
    653695
    654         printf("Init canvas..\n");
    655 
    656         window = window_open(display_svc, NULL,
    657             WINDOW_MAIN | WINDOW_DECORATED, "Font Editor");
    658         if (window == NULL) {
    659                 printf("Error creating window.\n");
    660                 rc = ENOMEM;
     696        printf("Init UI..\n");
     697
     698        rc = ui_create(display_spec, &ui);
     699        if (rc != EOK) {
     700                printf("Error initializing UI (%s)\n", display_spec);
    661701                goto error;
    662702        }
     
    665705        vh = 300;
    666706
    667         pixbuf = calloc(vw * vh, sizeof(pixel_t));
    668         if (pixbuf == NULL) {
    669                 printf("Error allocating memory for pixel buffer.\n");
    670                 rc = ENOMEM;
    671                 goto error;
    672         }
    673 
    674         surface = surface_create(vw, vh, pixbuf, 0);
    675         if (surface == NULL) {
    676                 printf("Error creating surface.\n");
    677                 rc = ENOMEM;
    678                 goto error;
    679         }
    680 
    681         /* Memory block pixbuf is now owned by surface */
    682         pixbuf = NULL;
    683 
    684         canvas = create_canvas(window_root(window), fedit, vw, vh,
    685             surface);
    686         if (canvas == NULL) {
    687                 printf("Error creating canvas.\n");
    688                 rc = ENOMEM;
    689                 goto error;
    690         }
    691 
    692         window_resize(window, 0, 0, vw + 10, vh + 30, WINDOW_PLACEMENT_ANY);
    693         window_exec(window);
    694 
    695         printf("Create canvas GC\n");
    696         rc = canvas_gc_create(canvas, surface, &cgc);
     707        rect.p0.x = 0;
     708        rect.p0.y = 0;
     709        rect.p1.x = vw;
     710        rect.p1.y = vh;
     711
     712        ui_wnd_params_init(&params);
     713        params.caption = "Font Editor";
     714
     715        /*
     716         * Compute window rectangle such that application area corresponds
     717         * to rect
     718         */
     719        ui_wdecor_rect_from_app(&rect, &wrect);
     720        off = wrect.p0;
     721        gfx_rect_rtranslate(&off, &wrect, &params.rect);
     722
     723        rc = ui_window_create(ui, &params, &window);
    697724        if (rc != EOK) {
    698                 printf("Error creating canvas GC.\n");
    699                 goto error;
    700         }
    701 
    702         gc = canvas_gc_get_ctx(cgc);
     725                printf("Error creating window.\n");
     726                goto error;
     727        }
     728
     729        ui_window_set_cb(window, &font_edit_window_cb, (void *) fedit);
     730
     731        rc = ui_window_get_app_gc(window, &gc);
     732        if (rc != EOK) {
     733                printf("Error creating graphic context.\n");
     734                goto error;
     735        }
    703736
    704737        if (fname == NULL) {
     
    755788        }
    756789
    757         sig_connect(&canvas->position_event, &canvas->widget,
    758             font_edit_pos_event);
    759         sig_connect(&canvas->keyboard_event, &canvas->widget,
    760             font_edit_kbd_event);
    761 
    762790        if (fname == NULL)
    763791                fname = "new.tpf";
    764792
    765         fedit->cgc = cgc;
     793        fedit->ui = ui;
     794        fedit->window = window;
    766795        fedit->gc = gc;
    767796        fedit->width = vw;
     
    790819        if (tface != NULL)
    791820                gfx_typeface_destroy(tface);
    792         if (surface != NULL)
    793                 surface_destroy(surface);
    794         if (pixbuf != NULL)
    795                 free(pixbuf);
    796821        if (window != NULL)
    797                 window_close(window);
     822                ui_window_destroy(window);
     823        if (ui != NULL)
     824                ui_destroy(ui);
    798825        if (fedit != NULL)
    799826                free(fedit);
     
    801828}
    802829
     830/** Destroy font editor.
     831 *
     832 * @param fedit Font editor
     833 */
     834static void font_edit_destroy(font_edit_t *fedit)
     835{
     836        gfx_glyph_bmp_close(fedit->gbmp);
     837        gfx_glyph_destroy(fedit->glyph);
     838        gfx_font_close(fedit->font);
     839        gfx_typeface_destroy(fedit->typeface);
     840        ui_window_destroy(fedit->window);
     841        ui_destroy(fedit->ui);
     842        free(fedit);
     843}
     844
    803845static void print_syntax(void)
    804846{
    805         printf("Syntax: fontedit [-d <display>] [<file.tpf>]\n");
     847        printf("Syntax: fontedit [-d <display-spec>] [<file.tpf>]\n");
    806848}
    807849
     
    809851{
    810852        errno_t rc;
    811         const char *display_svc = DISPLAY_DEFAULT;
     853        const char *display_spec = UI_DISPLAY_DEFAULT;
    812854        const char *fname = NULL;
    813855        font_edit_t *fedit;
     
    824866                        }
    825867
    826                         display_svc = argv[i++];
     868                        display_spec = argv[i++];
    827869                } else {
    828870                        printf("Invalid option '%s'.\n", argv[i]);
     
    845887        }
    846888
    847         rc = font_edit_create(display_svc, fname, &fedit);
     889        rc = font_edit_create(display_spec, fname, &fedit);
    848890        if (rc != EOK)
    849891                return 1;
     
    851893        (void) font_edit_paint(fedit);
    852894
    853         task_retval(0);
    854         async_manager();
    855 
     895        ui_run(fedit->ui);
     896        font_edit_destroy(fedit);
     897
     898        (void) font_edit_kbd_event;
     899        (void) font_edit_pos_event;
    856900        return 0;
    857901}
  • uspace/app/fontedit/fontedit.h

    rd942ca4 r66a2becf  
    4040#include <gfx/glyph_bmp.h>
    4141#include <gfx/typeface.h>
    42 #include <guigfx/canvas.h>
     42#include <ui/ui.h>
     43#include <ui/window.h>
    4344
    4445/** Font editor */
    4546typedef struct {
    46         /** Canvas GC */
    47         canvas_gc_t *cgc;
     47        /** UI */
     48        ui_t *ui;
     49        /** Window */
     50        ui_window_t *window;
    4851        /** Graphic context */
    4952        gfx_context_t *gc;
  • uspace/app/fontedit/meson.build

    rd942ca4 r66a2becf  
    2727#
    2828
    29 deps = [ 'gfx', 'guigfx', 'gfxfont' ]
     29deps = [ 'ui', 'gfx', 'gfxfont' ]
    3030src = files(
    3131        'fontedit.c',
  • uspace/lib/ui/include/ui/window.h

    rd942ca4 r66a2becf  
    5555extern ui_resource_t *ui_window_get_res(ui_window_t *);
    5656extern gfx_context_t *ui_window_get_gc(ui_window_t *);
     57extern errno_t ui_window_get_app_gc(ui_window_t *, gfx_context_t **);
    5758extern void ui_window_get_app_rect(ui_window_t *, gfx_rect_t *);
    5859extern errno_t ui_window_paint(ui_window_t *);
  • uspace/lib/ui/meson.build

    rd942ca4 r66a2becf  
    2727#
    2828
    29 deps = [ 'gfx', 'gfxfont', 'display' ]
     29deps = [ 'gfx', 'gfxfont', 'memgfx', 'display' ]
    3030src = files(
    3131        'src/control.c',
  • uspace/lib/ui/private/window.h

    rd942ca4 r66a2becf  
    5959        /** Window GC */
    6060        gfx_context_t *gc;
     61        /** Application area bitmap */
     62        gfx_bitmap_t *app_bmp;
     63        /** Application area GC */
     64        gfx_context_t *app_gc;
    6165        /** UI resource. Ideally this would be in ui_t. */
    6266        struct ui_resource *res;
  • uspace/lib/ui/src/window.c

    rd942ca4 r66a2becf  
    3636#include <display.h>
    3737#include <errno.h>
     38#include <gfx/bitmap.h>
    3839#include <gfx/context.h>
    3940#include <gfx/render.h>
     
    4142#include <io/pos_event.h>
    4243#include <mem.h>
     44#include <memgfx/memgc.h>
    4345#include <stdlib.h>
    4446#include <ui/control.h>
     
    7476        .move = wd_move
    7577};
     78
     79static void ui_window_app_update(void *, gfx_rect_t *);
    7680
    7781/** Initialize window parameters structure.
     
    223227}
    224228
     229/** Get UI resource from window.
     230 *
     231 * @param window Window
     232 * @return UI resource
     233 */
    225234ui_resource_t *ui_window_get_res(ui_window_t *window)
    226235{
     
    228237}
    229238
     239/** Get window GC.
     240 *
     241 * @param window Window
     242 * @return GC (relative to window)
     243 */
    230244gfx_context_t *ui_window_get_gc(ui_window_t *window)
    231245{
     
    233247}
    234248
     249/** Get window application area GC
     250 *
     251 * @param window Window
     252 * @param rgc Place to store GC (relative to application area)
     253 * @return EOK on success or an error code
     254 */
     255errno_t ui_window_get_app_gc(ui_window_t *window, gfx_context_t **rgc)
     256{
     257        gfx_bitmap_params_t params;
     258        gfx_bitmap_alloc_t alloc;
     259        gfx_rect_t rect;
     260        mem_gc_t *memgc;
     261        errno_t rc;
     262
     263        if (window->app_gc == NULL) {
     264                assert(window->app_bmp == NULL);
     265
     266                gfx_bitmap_params_init(&params);
     267
     268                /*
     269                 * The bitmap will have the same dimensions as the
     270                 * application rectangle, but start at 0,0.
     271                 */
     272                ui_window_get_app_rect(window, &rect);
     273                gfx_rect_rtranslate(&rect.p0, &rect, &params.rect);
     274
     275                rc = gfx_bitmap_create(window->gc, &params, NULL,
     276                    &window->app_bmp);
     277                if (rc != EOK)
     278                        return rc;
     279
     280                rc = gfx_bitmap_get_alloc(window->app_bmp, &alloc);
     281                if (rc != EOK) {
     282                        gfx_bitmap_destroy(window->app_bmp);
     283                        return rc;
     284                }
     285
     286                rc = mem_gc_create(&params.rect, &alloc, ui_window_app_update,
     287                    (void *) window, &memgc);
     288                if (rc != EOK) {
     289                        gfx_bitmap_destroy(window->app_bmp);
     290                        return rc;
     291                }
     292
     293                window->app_gc = mem_gc_get_ctx(memgc);
     294        }
     295
     296        *rgc = window->app_gc;
     297        return EOK;
     298}
     299
     300/** Get window application rectangle
     301 *
     302 * @param window Window
     303 * @param rect Place to store application rectangle
     304 */
    235305void ui_window_get_app_rect(ui_window_t *window, gfx_rect_t *rect)
    236306{
     
    241311}
    242312
     313/** Paint window
     314 *
     315 * @param window Window
     316 * @return EOK on success or an error code
     317 */
    243318errno_t ui_window_paint(ui_window_t *window)
    244319{
     
    428503}
    429504
     505/** Application area update callback
     506 *
     507 * @param arg Argument (ui_window_t *)
     508 * @param rect Rectangle to update
     509 */
     510static void ui_window_app_update(void *arg, gfx_rect_t *rect)
     511{
     512        ui_window_t *window = (ui_window_t *) arg;
     513        gfx_rect_t arect;
     514
     515        ui_window_get_app_rect(window, &arect);
     516
     517        /* Render bitmap rectangle inside the application area */
     518        (void) gfx_bitmap_render(window->app_bmp, rect, &arect.p0);
     519}
     520
    430521/** @}
    431522 */
  • uspace/lib/ui/test/window.c

    rd942ca4 r66a2becf  
    2929#include <gfx/context.h>
    3030#include <gfx/coord.h>
     31#include <gfx/render.h>
    3132#include <io/kbd_event.h>
    3233#include <io/pos_event.h>
     
    207208}
    208209
     210/** ui_window_get_app_gc() return valid GC */
     211PCUT_TEST(get_app_gc)
     212{
     213        errno_t rc;
     214        ui_t *ui = NULL;
     215        ui_wnd_params_t params;
     216        ui_window_t *window = NULL;
     217        gfx_context_t *gc;
     218
     219        rc = ui_create_disp(NULL, &ui);
     220        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     221
     222        ui_wnd_params_init(&params);
     223        params.caption = "Hello";
     224        params.rect.p0.x = 0;
     225        params.rect.p0.y = 0;
     226        params.rect.p0.x = 10;
     227        params.rect.p0.y = 10;
     228
     229        rc = ui_window_create(ui, &params, &window);
     230        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     231        PCUT_ASSERT_NOT_NULL(window);
     232
     233        rc = ui_window_get_app_gc(window, &gc);
     234        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     235        PCUT_ASSERT_NOT_NULL(gc);
     236
     237        rc = gfx_fill_rect(gc, &params.rect);
     238        PCUT_ASSERT_ERRNO_VAL(EOK, rc);
     239
     240        ui_window_destroy(window);
     241        ui_destroy(ui);
     242}
     243
    209244/** Test ui_window_paint() */
    210245PCUT_TEST(paint)
Note: See TracChangeset for help on using the changeset viewer.