Skip to content

Commit 81066ee

Browse files
committed
Fix display of Unicode text in many views
This commit also adds the strwidth function and consolidates the TDrawBuffer interface.
1 parent 0e0f488 commit 81066ee

File tree

10 files changed

+117
-97
lines changed

10 files changed

+117
-97
lines changed

include/tvision/drawbuf.h

+5-4
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class TDrawBuffer
4242

4343
void moveChar( ushort indent, char c, ushort attr, ushort count );
4444
void moveStr( ushort indent, const char _FAR *str, ushort attrs );
45+
void moveStr( ushort indent, const char _FAR *str, ushort attr, ushort width, ushort begin=0 );
4546
void moveCStr( ushort indent, const char _FAR *str, ushort attrs );
4647
void moveBuf( ushort indent, const void _FAR *source,
4748
ushort attr, ushort count );
@@ -52,10 +53,10 @@ class TDrawBuffer
5253

5354
#ifndef __BORLANDC__
5455
// Multibyte compatible operations
55-
56-
void moveStrEx( ushort indent, std::string_view str, ushort attrs );
57-
void moveCStrEx( ushort indent, std::string_view str, ushort attrs );
58-
void moveBufEx( ushort indent, TScreenCell *source, ushort attr, ushort count );
56+
void moveStr( ushort indent, std::string_view str, ushort attrs );
57+
void moveStr( ushort indent, std::string_view str, ushort attr, ushort width, ushort begin=0 );
58+
void moveCStr( ushort indent, std::string_view str, ushort attrs );
59+
void moveBuf( ushort indent, TScreenCell *source, ushort attr, ushort count );
5960
#endif
6061

6162
#ifdef __FLAT__

include/tvision/util.h

+4-2
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,10 @@ const char *historyStr( uchar id, int index );
4545
void historyAdd( uchar id, const char * );
4646

4747
int cstrlen( const char * );
48+
int strwidth( const char * );
4849
#ifndef __BORLANDC__
49-
int cstrlen(std::string_view s);
50+
int cstrlen( std::string_view s );
51+
int strwidth( std::string_view s );
5052
#endif
5153

5254
class _FAR TView;
@@ -67,7 +69,7 @@ void getCurDir( char *dir );
6769

6870
Boolean isWild( const char *f );
6971

70-
char *strnzcpy( char *dest, const char *src, size_t n ); // misc.cpp
72+
char *strnzcpy( char *dest, const char *src, size_t n );
7173

7274
unsigned int fast_utoa( uint value, char *buffer );
7375

source/tvision/drivers.cpp

+59-67
Original file line numberDiff line numberDiff line change
@@ -113,28 +113,12 @@ I POP DS
113113
*(uchar *)dest++ = *s++;
114114

115115
#else
116-
return moveStrEx(indent, std::string_view {(const char*) source, count}, attr);
117-
#if 0
118-
TScreenCell *dest = &data[indent];
119-
TScreenCell *limit = &data[dataLength];
120-
uchar *s = (uchar *) source;
121-
if (attr)
122-
for (; dest < limit && count; --count, ++s, ++dest)
123-
{
124-
TScreenCell c {};
125-
c.Char = (uchar) *s;
126-
c.Attr = (uchar) attr;
127-
*dest = c;
128-
}
129-
else
130-
while (dest < limit && count--)
131-
*dest++ = TScreenCell::fromPair(*s++);
132-
#endif
116+
return moveStr(indent, std::string_view {(const char*) source, count}, attr);
133117
#endif
134118
}
135119

136120
#ifndef __BORLANDC__
137-
void TDrawBuffer::moveBufEx(ushort indent, TScreenCell *source, ushort attr, ushort count)
121+
void TDrawBuffer::moveBuf(ushort indent, TScreenCell *source, ushort attr, ushort count)
138122
{
139123
TScreenCell *dest = &data[indent];
140124
TScreenCell *limit = &data[dataLength];
@@ -317,35 +301,12 @@ I POP DS
317301
}
318302
}
319303
#else
320-
return moveCStrEx(indent, str, attrs);
321-
#if 0
322-
TScreenCell *dest = &data[indent];
323-
TScreenCell *limit = &data[dataLength];
324-
uchar c;
325-
int toggle = 1;
326-
uchar curAttr = ((uchar *)&attrs)[0];
327-
328-
for (; dest < limit && (c = *str); ++str)
329-
{
330-
if (c == '~')
331-
{
332-
curAttr = ((uchar *) &attrs)[toggle];
333-
toggle = 1 - toggle;
334-
}
335-
else
336-
{
337-
TScreenCell cell {};
338-
cell.Char = (uchar) c;
339-
cell.Attr = (uchar) curAttr;
340-
*dest++ = cell;
341-
}
342-
}
343-
#endif
304+
return moveCStr(indent, std::string_view {str}, attrs);
344305
#endif
345306
}
346307

347308
#ifndef __BORLANDC__
348-
void TDrawBuffer::moveCStrEx( ushort indent, std::string_view str, ushort attrs )
309+
void TDrawBuffer::moveCStr( ushort indent, std::string_view str, ushort attrs )
349310
{
350311
size_t i = indent, j = 0;
351312
int toggle = 1;
@@ -434,34 +395,12 @@ I POP DS
434395
while (dest < limit && *str)
435396
*(uchar *)dest++ = *str++;
436397
#else
437-
return moveStrEx(indent, str, attr);
438-
#if 0
439-
TScreenCell *dest = &data[indent];
440-
TScreenCell *limit = &data[dataLength];
441-
uchar c;
442-
443-
if (attr)
444-
for (; dest < limit && (c = *str); ++str, ++dest)
445-
{
446-
TScreenCell cell {};
447-
cell.Char = (uchar) c;
448-
cell.Attr = (uchar) attr;
449-
*dest = cell;
450-
}
451-
else
452-
while (dest < limit && *str)
453-
{
454-
auto cell = dest->Cell;
455-
cell.Char = (uchar) *str++;
456-
cell.extraWidth = 0;
457-
*dest++ = cell;;
458-
}
459-
#endif
398+
return moveStr(indent, std::string_view {str}, attr);
460399
#endif
461400
}
462401

463402
#ifndef __BORLANDC__
464-
void TDrawBuffer::moveStrEx( ushort indent, std::string_view str, ushort attr )
403+
void TDrawBuffer::moveStr( ushort indent, std::string_view str, ushort attr )
465404
{
466405
size_t i = indent, j = 0;
467406

@@ -477,6 +416,59 @@ void TDrawBuffer::moveStrEx( ushort indent, std::string_view str, ushort attr )
477416
}
478417
#endif
479418

419+
/*------------------------------------------------------------------------*/
420+
/* */
421+
/* TDrawBuffer::moveStr (2) */
422+
/* */
423+
/* arguments: */
424+
/* */
425+
/* indent - character position within the buffer where the data */
426+
/* is to go */
427+
/* */
428+
/* str - pointer to a 0-terminated string of characters to */
429+
/* be moved into the buffer */
430+
/* */
431+
/* attr - text attribute to be put into the buffer with each */
432+
/* character in the string. */
433+
/* */
434+
/* width - number of display columns to be copied from str. */
435+
/* */
436+
/* begin - initial display column in str where to start counting. */
437+
/* */
438+
/*------------------------------------------------------------------------*/
439+
440+
void TDrawBuffer::moveStr( ushort indent, const char _FAR *str, ushort attr, ushort width, ushort begin )
441+
{
442+
#ifdef __BORLANDC__
443+
int len = 0;
444+
while (str[len] && len < int(begin + width))
445+
++len;
446+
len -= begin;
447+
if (len > 0)
448+
moveBuf(indent, str + begin, attr, min(width, len));
449+
#else
450+
moveStr(indent, std::string {str}, attr, width, begin);
451+
#endif
452+
}
453+
454+
#ifndef __BORLANDC__
455+
void TDrawBuffer::moveStr( ushort indent, std::string_view str, ushort attr, ushort width, ushort begin )
456+
{
457+
size_t s = 0, remainder = 0;
458+
utf8wseek(str, s, remainder, begin);
459+
if (remainder)
460+
moveChar(indent, ' ', attr, remainder);
461+
size_t d = indent + remainder;
462+
size_t limit = std::min(dataLength, d + width);
463+
while (d < limit && s < str.size())
464+
{
465+
if (attr)
466+
data[d].Attr = (uchar) attr;
467+
utf8read(&data[d], dataLength - d, d, {&str[s], str.size() - s}, s);
468+
}
469+
}
470+
#endif
471+
480472
#ifdef __FLAT__
481473
TDrawBuffer::TDrawBuffer() {
482474
// This makes it possible to create TDrawBuffers for big screen widths.

source/tvision/drivers2.cpp

+37-3
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,16 @@ const ushort arrowCodes[] =
7474

7575
int cstrlen( const char *s )
7676
{
77-
#ifndef __BORLANDC__
78-
return cstrlen(std::string_view {s});
79-
#else
77+
#ifdef __BORLANDC__
8078
int len = 0;
8179
while( *s != EOS )
8280
{
8381
if( *s++ != '~' )
8482
len++;
8583
}
8684
return len;
85+
#else
86+
return cstrlen(std::string_view {s});
8787
#endif
8888
}
8989

@@ -101,3 +101,37 @@ int cstrlen( std::string_view s )
101101
return width;
102102
}
103103
#endif
104+
105+
/*------------------------------------------------------------------------*/
106+
/* */
107+
/* strwidth */
108+
/* */
109+
/* argument: */
110+
/* */
111+
/* s - pointer to 0-terminated string */
112+
/* */
113+
/* returns */
114+
/* */
115+
/* displayed length of string. */
116+
/* */
117+
/*------------------------------------------------------------------------*/
118+
119+
int strwidth( const char *s )
120+
{
121+
#ifdef __BORLANDC__
122+
return strlen(s);
123+
#else
124+
return strwidth(std::string_view {s});
125+
#endif
126+
}
127+
128+
#ifndef __BORLANDC__
129+
int strwidth( std::string_view s )
130+
{
131+
std::mbstate_t state = {};
132+
size_t i = 0, width = 0;
133+
while (i < s.size())
134+
utf8next(s.substr(i, s.size() - i), i, width, state);
135+
return width;
136+
}
137+
#endif

source/tvision/help.cpp

+4-8
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,6 @@ void THelpViewer::draw()
9494
TDrawBuffer b;
9595
size_t bufLength = b.length();
9696
char *line = (char*) alloca(bufLength);
97-
char *buffer = (char*) alloca(bufLength);
98-
char *bufPtr;
9997
int i, j, l;
10098
int keyCount;
10199
ushort normal, keyword, selKeyword, c;
@@ -122,13 +120,11 @@ void THelpViewer::draw()
122120
for (i = 1; i <= size.y; ++i)
123121
{
124122
b.moveChar(0, ' ', normal, size.x);
125-
strcpy(line, topic->getLine(i + delta.y, buffer, bufLength));
126-
if (strlen(line) > delta.x)
123+
memset(line, 0, bufLength);
124+
topic->getLine(i + delta.y, line, bufLength-1);
125+
if (strwidth(line) > delta.x)
127126
{
128-
bufPtr = line + delta.x;
129-
strncpy(buffer, bufPtr, size.x);
130-
buffer[size.x] = 0;
131-
b.moveStr(0, buffer, normal);
127+
b.moveStr(0, line, normal, size.x, delta.x);
132128
}
133129
else
134130
b.moveStr(0, "", normal);

source/tvision/tframe.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ void TFrame::draw()
8787
l = max( l, 0 );
8888
i = (width - l) >> 1;
8989
b.putChar( i-1, ' ' );
90-
b.moveBuf( i, title, cTitle, l );
90+
b.moveStr( i, title, cTitle, l );
9191
b.putChar( i+l, ' ' );
9292
}
9393
}

source/tvision/thstview.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ int THistoryViewer::historyWidth()
9090
int count = historyCount( historyId );
9191
for( int i = 0; i < count; i++ )
9292
{
93-
int T = strlen( historyStr( historyId, i ) );
93+
int T = strwidth( historyStr( historyId, i ) );
9494
width = max( width, T );
9595
}
9696
return width;

source/tvision/tinputli.cpp

+2-7
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ Boolean TInputLine::canScroll( int delta )
7777
return Boolean( firstPos > 0 );
7878
else
7979
if( delta > 0 )
80-
return Boolean( strlen(data) - firstPos + 2 > size.x );
80+
return Boolean( strwidth(data) - firstPos + 2 > size.x );
8181
else
8282
return False;
8383
}
@@ -103,10 +103,7 @@ void TInputLine::draw()
103103
b.moveChar( 0, ' ', color, size.x );
104104
if( size.x > 1 )
105105
{
106-
char buf[256];
107-
strncpy( buf, data+firstPos, size.x - 2 );
108-
buf[size.x - 2 ] = EOS;
109-
b.moveStr( 1, buf, color );
106+
b.moveStr( 1, data, color, size.x - 1, firstPos);
110107
}
111108
if( canScroll(1) )
112109
b.moveChar( size.x-1, rightArrow, getColor(4), 1 );
@@ -317,8 +314,6 @@ void TInputLine::handleEvent( TEvent& event )
317314
{
318315
strcpy( data+curPos-1, data+curPos );
319316
curPos--;
320-
if( firstPos > 0 )
321-
firstPos--;
322317
checkValid(True);
323318
}
324319
break;

source/tvision/tlstview.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -131,8 +131,8 @@ void TListViewer::draw()
131131
if (indent < 255)
132132
{
133133
char text[256] = {0};
134-
getText( text, item, min(colWidth + indent, 255) );
135-
b.moveStr( curCol+1, text + indent, color );
134+
getText( text, item, 255 );
135+
b.moveStr( curCol+1, text, color, colWidth, indent );
136136
}
137137
if( showMarkers )
138138
{

source/tvision/tmenubox.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static TRect getRect( const TRect& bounds, TMenu *aMenu )
3737
l += 3;
3838
else
3939
if( p->param != 0 )
40-
l += cstrlen(p->param) + 2;
40+
l += strwidth(p->param) + 2;
4141
w = max( l, w );
4242
}
4343
h++;
@@ -110,7 +110,7 @@ void TMenuBox::draw()
110110
if( p->command == 0 )
111111
b.putChar( size.x-4, 16 );
112112
else if( p->param != 0 )
113-
b.moveStr( size.x-3-strlen(p->param),
113+
b.moveStr( size.x-3-strwidth(p->param),
114114
p->param,
115115
color);
116116
}

0 commit comments

Comments
 (0)