mirror of
https://github.com/dankamongmen/notcurses.git
synced 2024-11-20 03:25:47 +00:00
fix LayoutFillsPlaneNoSpaces problems #815
This commit is contained in:
parent
1664e64617
commit
243cbd6a92
@ -1662,7 +1662,8 @@ int ncplane_puttext(ncplane* n, int y, ncalign_e align, const char* text, size_t
|
|||||||
const char* linestart = text;
|
const char* linestart = text;
|
||||||
int x = 0; // number of columns consumed for this line
|
int x = 0; // number of columns consumed for this line
|
||||||
do{
|
do{
|
||||||
const char* breaker = NULL;
|
const char* breaker = NULL; // where the last wordbreaker starts
|
||||||
|
int breakercol = 0; // column of the last wordbreaker
|
||||||
// figure how much text to output on this line
|
// figure how much text to output on this line
|
||||||
mbstate_t mbstate = {};
|
mbstate_t mbstate = {};
|
||||||
int width;
|
int width;
|
||||||
@ -1671,7 +1672,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.
|
// not a space, it won't be printed, and we carry the word forward.
|
||||||
// FIXME what ought be done with \n or multiple spaces?
|
// FIXME what ought be done with \n or multiple spaces?
|
||||||
while(*text && x <= dimx){
|
while(*text && x <= dimx){
|
||||||
fprintf(stderr, "laying out [%s] at %d <= %d, %zu\n", linestart, x, dimx, text - linestart);
|
//fprintf(stderr, "laying out [%s] at %d <= %d, %zu\n", linestart, x, dimx, text - linestart);
|
||||||
wchar_t w;
|
wchar_t w;
|
||||||
size_t consumed = mbrtowc(&w, text, MB_CUR_MAX, &mbstate);
|
size_t consumed = mbrtowc(&w, text, MB_CUR_MAX, &mbstate);
|
||||||
if(consumed == (size_t)-2 || consumed == (size_t)-1){
|
if(consumed == (size_t)-2 || consumed == (size_t)-1){
|
||||||
@ -1689,10 +1690,11 @@ fprintf(stderr, "laying out [%s] at %d <= %d, %zu\n", linestart, x, dimx, text -
|
|||||||
continue; // don't emit leading whitespace, or count it
|
continue; // don't emit leading whitespace, or count it
|
||||||
}else{
|
}else{
|
||||||
breaker = text;
|
breaker = text;
|
||||||
|
breakercol = x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
width = wcwidth(w);
|
width = wcwidth(w);
|
||||||
fprintf(stderr, "have char %lc (%d)\n", w, width);
|
//fprintf(stderr, "have char %lc (%d) (%zu)\n", w, width, text - linestart);
|
||||||
if(width < 0){
|
if(width < 0){
|
||||||
width = 0;
|
width = 0;
|
||||||
}
|
}
|
||||||
@ -1702,31 +1704,30 @@ fprintf(stderr, "have char %lc (%d)\n", w, width);
|
|||||||
x += width;
|
x += width;
|
||||||
text += consumed;
|
text += consumed;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "OUT! %s %zu\n", linestart, text - linestart);
|
//fprintf(stderr, "OUT! %s %zu %d\n", linestart, text - linestart, x);
|
||||||
int carrybytes = 0;
|
|
||||||
bool overlong = false; // ugh
|
bool overlong = false; // ugh
|
||||||
// if we have no breaker, we got a single word that was longer than our
|
// 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.
|
// line. print what we can and move along. if *text is nul, we're done.
|
||||||
if(!*text || breaker == NULL){
|
if(!*text || breaker == NULL){
|
||||||
breaker = text/* + 1*/;
|
breaker = text;
|
||||||
|
breakercol = dimx;
|
||||||
}else{
|
}else{
|
||||||
// if the word on which we ended is overlong (longer than the plane is
|
// if the word on which we ended is overlong (longer than the plane is
|
||||||
// wide), go ahead and start printing it where it starts. otherwise, punt
|
// wide), go ahead and start printing it where it starts. otherwise, punt
|
||||||
// it to the next line, to avoid breaking it across lines.
|
// it to the next line, to avoid breaking it across lines.
|
||||||
if(overlong_word(breaker + 1, dimx)){
|
if(overlong_word(breaker + 1, dimx)){
|
||||||
breaker = text;
|
breaker = text;
|
||||||
|
breakercol = dimx;
|
||||||
overlong = true;
|
overlong = true;
|
||||||
fprintf(stderr, "NEW BREAKER: %s\n", breaker);
|
//fprintf(stderr, "NEW BREAKER: %s\n", breaker);
|
||||||
}else{
|
|
||||||
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){
|
if(breaker != linestart){
|
||||||
totalcols += x;
|
totalcols += breakercol;
|
||||||
const int xpos = ncplane_align(n, align, x);
|
const int xpos = ncplane_align(n, align, breakercol);
|
||||||
// blows out if we supply a y beyond leny
|
// 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(ncplane_putnstr_yx(n, y, xpos, breaker - linestart, linestart) <= 0){
|
||||||
if(bytes){
|
if(bytes){
|
||||||
*bytes = linestart - beginning;
|
*bytes = linestart - beginning;
|
||||||
@ -1734,7 +1735,8 @@ fprintf(stderr, "y: %d %ld %.*s\n", y, breaker - linestart, (int)(breaker - line
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
x = carrybytes;
|
//fprintf(stderr, "x gets breakercol: %d\n", breakercol);
|
||||||
|
x = breakercol;
|
||||||
if(breaker == text || overlong){
|
if(breaker == text || overlong){
|
||||||
linestart = breaker;
|
linestart = breaker;
|
||||||
}else{
|
}else{
|
||||||
@ -2458,7 +2460,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 ncplane_putnstr_yx(struct ncplane* n, int y, int x, size_t s, const char* gclusters){
|
||||||
int ret = 0;
|
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
|
// FIXME speed up this blissfully naive solution
|
||||||
while((size_t)ret < s && *gclusters){
|
while((size_t)ret < s && *gclusters){
|
||||||
int wcs;
|
int wcs;
|
||||||
|
@ -90,13 +90,13 @@ TEST_CASE("TextLayout") {
|
|||||||
auto sp = ncplane_new(nc_, 2, 6, 0, 0, nullptr);
|
auto sp = ncplane_new(nc_, 2, 6, 0, 0, nullptr);
|
||||||
REQUIRE(sp);
|
REQUIRE(sp);
|
||||||
size_t bytes;
|
size_t bytes;
|
||||||
const char boundstr[] = "a 血的神 m公";
|
const char boundstr[] = "a 血的神";
|
||||||
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes));
|
CHECK(0 < ncplane_puttext(sp, 0, NCALIGN_CENTER, boundstr, &bytes));
|
||||||
CHECK(0 == notcurses_render(nc_));
|
CHECK(0 == notcurses_render(nc_));
|
||||||
CHECK(bytes == strlen(boundstr));
|
CHECK(bytes == strlen(boundstr));
|
||||||
char* line = ncplane_contents(sp, 0, 0, -1, -1);
|
char* line = ncplane_contents(sp, 0, 0, -1, -1);
|
||||||
REQUIRE(line);
|
REQUIRE(line);
|
||||||
CHECK(0 == strcmp(line, "a 血的神 m公"));
|
CHECK(0 == strcmp(line, "a血的神"));
|
||||||
free(line);
|
free(line);
|
||||||
ncplane_destroy(sp);
|
ncplane_destroy(sp);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user