From 97517d0473e8e513cb4bcb245d60118c8c97071c Mon Sep 17 00:00:00 2001 From: nick black Date: Tue, 16 Jun 2020 01:22:40 -0400 Subject: [PATCH] ncplane_puttext: another test, another bug #691 --- src/lib/notcurses.c | 30 ++++++++++++++++-------------- tests/layout.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index ed93a9df4..59c8a95f6 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1510,6 +1510,7 @@ int ncplane_puttext(ncplane* n, int y, ncalign_e align, const char* text, size_t // might catch a space, in which case we want breaker updated. if it's // not a space, it won't be printed, and we carry the word forward. // FIXME what ought be done with \n or multiple spaces? +//fprintf(stderr, "laying out [%s] at %d (%d)\n", linestart, x, dimx); while(*text && x <= dimx){ wchar_t w; size_t consumed = mbrtowc(&w, text, MB_CUR_MAX, &mbstate); @@ -1538,27 +1539,28 @@ int ncplane_puttext(ncplane* n, int y, ncalign_e align, const char* text, size_t x += width; text += consumed; } - int carrycols = 0; - if(x > dimx){ - // the last character was one past the amount we can print. - // set carrycols to the amount since breaker. - carrycols = text - breaker; - } - totalcols += (breaker - linestart); - const int xpos = ncplane_align(n, align, x); +//fprintf(stderr, "exited at %d (%d) looking at %.*s\n", x, dimx, breaker - linestart, linestart); + // if we have no breaker, we got a word that was longer than our line; + // print what we can and move along. if *text is nul, we're done. if(!*text || breaker == NULL){ breaker = text; } - // blows out if we supply a y beyond leny - if(ncplane_putnstr_yx(n, y, xpos, breaker - linestart, linestart) < 0){ - if(bytes){ - *bytes = linestart - beginning; + int carrycols = 0; + carrycols = text - breaker; + if(breaker != linestart){ + totalcols += (breaker - linestart); + const int xpos = ncplane_align(n, align, x); + // blows out if we supply a y beyond leny + if(ncplane_putnstr_yx(n, y, xpos, breaker - linestart, linestart) < 0){ + if(bytes){ + *bytes = linestart - beginning; + } + return -1; } - return -1; } x = carrycols; linestart = breaker + 1; - ++y; // FIXME scrolling! + ++y; // FIXME scrolling!??!! }while(*text); if(bytes){ *bytes = text - beginning; diff --git a/tests/layout.cpp b/tests/layout.cpp index 40cc98759..f12245f7c 100644 --- a/tests/layout.cpp +++ b/tests/layout.cpp @@ -85,6 +85,30 @@ TEST_CASE("TextLayout") { ncplane_destroy(sp); } + // lay out text where a word crosses the boundary + SUBCASE("LayoutCrossBoundary") { + auto sp = ncplane_new(nc_, 3, 10, 0, 0, nullptr); + REQUIRE(sp); + size_t bytes; + const char boundstr[] = "my grasping arms"; + CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes)); + CHECK(0 == notcurses_render(nc_)); + CHECK(bytes == strlen(boundstr)); + char* line = ncplane_contents(sp, 0, 0, 1, 10); + REQUIRE(line); + CHECK(0 == strcmp(line, "my")); + free(line); + line = ncplane_contents(sp, 1, 0, 1, 10); + REQUIRE(line); + CHECK(0 == strcmp(line, "grasping")); + free(line); + line = ncplane_contents(sp, 2, 0, 1, 10); + REQUIRE(line); + CHECK(0 == strcmp(line, "arms")); + free(line); + ncplane_destroy(sp); + } + CHECK(0 == notcurses_stop(nc_)); }