From 1664e646177ee55032c8972691ff09fd18c87b54 Mon Sep 17 00:00:00 2001 From: nick black Date: Thu, 23 Jul 2020 03:19:35 -0400 Subject: [PATCH] add LayoutCrossBoundaryWide unit test #815 --- src/lib/notcurses.c | 20 ++++++++++---------- tests/layout.cpp | 16 ++++++++++++++++ 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/lib/notcurses.c b/src/lib/notcurses.c index b1a8c511c..c92e711ab 100644 --- a/src/lib/notcurses.c +++ b/src/lib/notcurses.c @@ -1671,7 +1671,7 @@ int ncplane_puttext(ncplane* n, int y, ncalign_e align, const char* text, size_t // not a space, it won't be printed, and we carry the word forward. // FIXME what ought be done with \n or multiple spaces? while(*text && x <= dimx){ -//fprintf(stderr, "laying out [%s] at %d (%d)\n", linestart, x, dimx); +fprintf(stderr, "laying out [%s] at %d <= %d, %zu\n", linestart, x, dimx, text - linestart); wchar_t w; size_t consumed = mbrtowc(&w, text, MB_CUR_MAX, &mbstate); if(consumed == (size_t)-2 || consumed == (size_t)-1){ @@ -1692,7 +1692,7 @@ int ncplane_puttext(ncplane* n, int y, ncalign_e align, const char* text, size_t } } width = wcwidth(w); -//fprintf(stderr, "have non-wordbreak char %lc (%d)\n", w, width); +fprintf(stderr, "have char %lc (%d)\n", w, width); if(width < 0){ width = 0; } @@ -1702,8 +1702,8 @@ int ncplane_puttext(ncplane* n, int y, ncalign_e align, const char* text, size_t x += width; text += consumed; } -//fprintf(stderr, "OUT! %s %zu\n", linestart, text - linestart); - int carrycols = 0; +fprintf(stderr, "OUT! %s %zu\n", linestart, text - linestart); + int carrybytes = 0; bool overlong = false; // ugh // if we have no breaker, we got a single word that was longer than our // line. print what we can and move along. if *text is nul, we're done. @@ -1716,17 +1716,17 @@ int ncplane_puttext(ncplane* n, int y, ncalign_e align, const char* text, size_t if(overlong_word(breaker + 1, dimx)){ breaker = text; overlong = true; -//fprintf(stderr, "NEW BREAKER: %s\n", breaker); +fprintf(stderr, "NEW BREAKER: %s\n", breaker); }else{ - carrycols = text - breaker; + carrybytes = text - breaker; } } -//fprintf(stderr, "exited at %d (%d) %zu looking at [%.*s]\n", x, dimx, breaker - linestart, (int)(breaker - linestart), linestart); +fprintf(stderr, "exited at %d (%d) %zu looking at [%.*s]\n", x, dimx, breaker - linestart, (int)(breaker - linestart), linestart); if(breaker != linestart){ totalcols += x; const int xpos = ncplane_align(n, align, x); // blows out if we supply a y beyond leny -//fprintf(stderr, "y: %d %ld %.*s\n", y, breaker - linestart, (int)(breaker - linestart), linestart); +fprintf(stderr, "y: %d %ld %.*s\n", y, breaker - linestart, (int)(breaker - linestart), linestart); if(ncplane_putnstr_yx(n, y, xpos, breaker - linestart, linestart) <= 0){ if(bytes){ *bytes = linestart - beginning; @@ -1734,7 +1734,7 @@ int ncplane_puttext(ncplane* n, int y, ncalign_e align, const char* text, size_t return -1; } } - x = carrycols; + x = carrybytes; if(breaker == text || overlong){ linestart = breaker; }else{ @@ -2458,7 +2458,7 @@ int ncplane_putnstr_aligned(struct ncplane* n, int y, ncalign_e align, size_t s, int ncplane_putnstr_yx(struct ncplane* n, int y, int x, size_t s, const char* gclusters){ int ret = 0; -//fprintf(stderr, "PUT %zu at %d/%d [%.*s]\n", s, y, x, (int)s, gclusters); +fprintf(stderr, "PUT %zu at %d/%d [%.*s]\n", s, y, x, (int)s, gclusters); // FIXME speed up this blissfully naive solution while((size_t)ret < s && *gclusters){ int wcs; diff --git a/tests/layout.cpp b/tests/layout.cpp index 0f3d53683..ad746530d 100644 --- a/tests/layout.cpp +++ b/tests/layout.cpp @@ -85,6 +85,22 @@ TEST_CASE("TextLayout") { ncplane_destroy(sp); } + // lay out text where a wide word crosses the boundary + SUBCASE("LayoutCrossBoundaryWide") { + auto sp = ncplane_new(nc_, 2, 6, 0, 0, nullptr); + REQUIRE(sp); + size_t bytes; + const char boundstr[] = "a 血的神 m公"; + 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, -1); + REQUIRE(line); + CHECK(0 == strcmp(line, "a 血的神 m公")); + free(line); + ncplane_destroy(sp); + } + // a long word (one requiring a split no matter what) ought not force the // next line, but instead be printed where it starts SUBCASE("LayoutTransPlanar") {