Skip to content

Commit

Permalink
TStaticText: add Unicode support
Browse files Browse the repository at this point in the history
  • Loading branch information
magiblot committed Aug 17, 2020
1 parent b8cedd4 commit 7b15d45
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 19 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ void TDrawBuffer::moveBuf(ushort indent, const TScreenCell *source, ushort count
```
In case you happen to have an array of `TScreenCell`, this method allows you to copy them into a `TDrawBuffer`.
There are other useful unicode-aware functions:
There are other useful Unicode-aware functions:
```c++
int cstrlen(const char *s);
Expand All @@ -339,7 +339,7 @@ The functions above depend on the following lower-level functions. You will need
```c++
size_t TText::next(TStringView text);
size_t TText::prev(TStringView text, size_t index);
size_t TText::wseek(TStringView text, int count);
size_t TText::wseek(TStringView text, int count, Boolean incRemainder=True);
#ifndef __BORLANDC__
void TText::eat(TScreenCell *cell, size_t n, size_t &width, TStringView text, size_t &bytes);
void TText::next(TStringView text, size_t &bytes, size_t &width);
Expand Down Expand Up @@ -429,6 +429,7 @@ The overload of `moveStr` used here is `TDrawBuffer::moveStr(ushort indent, TStr
Support for creating Unicode-aware views is in place, but some views that are part of the original Turbo Vision library have not been adapted to handle Unicode.

* At least `TFrame`, `THistoryViewer`, `TListViewer` and `TMenuBox` are able to display Unicode text properly.
* Automatic shortcuts in `TMenuBox` won't work with Unicode text, as shortcuts are still compared against `event.keyDown.charScan.charCode`.
* `TInputLine` can display and process Unicode text.
* Word wrapping in `TStaticText` is Unicode-aware.
* Automatic shortcuts in `TMenuBox` won't work with Unicode text, as shortcuts are still compared against `event.keyDown.charScan.charCode`.
* `TEditor` assumes a single-byte encoding both when handling input events and when displaying text. So it won't display UTF-8 but at least it has a consistent behaviour.
28 changes: 18 additions & 10 deletions include/tvision/ttext.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ class TText {

static size_t next(TStringView text);
static size_t prev(TStringView text, size_t index);
static size_t wseek(TStringView text, int count);
static size_t wseek(TStringView text, int count, Boolean incRemainder=True);

#ifndef __BORLANDC__
static void eat(TScreenCell *cell, size_t n, size_t &width, TStringView text, size_t &bytes);
Expand All @@ -139,14 +139,14 @@ inline size_t TText::next(TStringView text)
return text.size() ? 1 : 0;
}

inline size_t TText::prev(TStringView text, size_t index)
inline size_t TText::prev(TStringView, size_t index)
{
return index ? 1 : 0;
}

inline size_t TText::wseek(TStringView text, int count)
inline size_t TText::wseek(TStringView text, int count, Boolean)
{
return count > 0 ? count : 0;
return count > 0 ? min(count, text.size()) : 0;
}

#else
Expand Down Expand Up @@ -182,13 +182,16 @@ inline size_t TText::prev(TStringView text, size_t index)
return 0;
}

inline size_t TText::wseek(TStringView text, int count)
inline size_t TText::wseek(TStringView text, int count, Boolean incRemainder)
// Seeks a string by an amount of display columns ('count'). If that amount
// partially overlaps a multi-column character, the whole character is included.
// partially overlaps a multi-column character, the whole character is included,
// unless 'incRemainder' is False.
// Returns the number of bytes seeked.
{
size_t index = 0, remainder = 0;
wseek(text, index, remainder, count);
if (!incRemainder && remainder)
index -= TText::prev(text, index);
return index;
}

Expand Down Expand Up @@ -277,14 +280,19 @@ inline void TText::wseek(TStringView text, size_t &index, size_t &remainder, int
// * count: number of columns to seek.
{
if (count > 0) {
while (count > 0 && index < text.size()) {
while (index < text.size()) {
size_t width = 0;
TText::next({&text[index], text.size() - index}, index, width);
count -= width;
if (count <= 0) {
// Immediately return when the requested width is exceeded.
remainder = -count;
return;
}
}
remainder = -count;
} else
remainder = 0;
}
// No remainder when the end of string was reached.
remainder = 0;
}

#endif // __BORLANDC__
Expand Down
14 changes: 8 additions & 6 deletions source/tvision/tstatict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,25 +65,27 @@ void TStaticText::draw()
++p;
}
i = p;
int last = i + TText::wseek(TStringView(&s[i], l-i), size.x, False);
do {
j = p;
while ((p < l) && (s[p] == ' '))
++p;
while ((p < l) && (s[p] != ' ') && (s[p] != '\n'))
++p;
} while ((p < l) && (p < i + size.x) && (s[p] != '\n'));
if (p > i + size.x)
p += TText::next(TStringView(&s[p], l-p));
} while ((p < l) && (p < last) && (s[p] != '\n'));
if (p > last)
{
if (j > i)
p = j;
else
p = i + size.x;
p = last;
}
int width = strwidth(TStringView(&s[i], p-i));
if (center == True)
j = (size.x - p + i) / 2 ;
j = (size.x - width) / 2 ;
else
j = 0;
b.moveBuf(j, &s[i], color, (p - i));
b.moveStr(j, TStringView(&s[i], l-i), color, (ushort) width);
while ((p < l) && (s[p] == ' '))
p++;
if ((p < l) && (s[p] == '\n'))
Expand Down

0 comments on commit 7b15d45

Please sign in to comment.