get_wraped_wxString(): Adapted to work with UTF8
This commit is contained in:
parent
1fe9e5231b
commit
be60775077
@ -77,6 +77,7 @@ extern std::string normalize_utf8_nfc(const char *src);
|
|||||||
// Returns next utf8 sequence length. =number of bytes in string, that creates together one utf-8 character.
|
// Returns next utf8 sequence length. =number of bytes in string, that creates together one utf-8 character.
|
||||||
// Starting at pos. ASCII characters returns 1. Works also if pos is in the middle of the sequence.
|
// Starting at pos. ASCII characters returns 1. Works also if pos is in the middle of the sequence.
|
||||||
extern size_t get_utf8_sequence_length(const std::string& text, size_t pos = 0);
|
extern size_t get_utf8_sequence_length(const std::string& text, size_t pos = 0);
|
||||||
|
extern size_t get_utf8_sequence_length(const char *seq, size_t size);
|
||||||
|
|
||||||
// Safely rename a file even if the target exists.
|
// Safely rename a file even if the target exists.
|
||||||
// On Windows, the file explorer (or anti-virus or whatever else) often locks the file
|
// On Windows, the file explorer (or anti-virus or whatever else) often locks the file
|
||||||
|
@ -866,8 +866,13 @@ std::string normalize_utf8_nfc(const char *src)
|
|||||||
size_t get_utf8_sequence_length(const std::string& text, size_t pos)
|
size_t get_utf8_sequence_length(const std::string& text, size_t pos)
|
||||||
{
|
{
|
||||||
assert(pos < text.size());
|
assert(pos < text.size());
|
||||||
|
return get_utf8_sequence_length(text.c_str() + pos, text.size() - pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t get_utf8_sequence_length(const char *seq, size_t size)
|
||||||
|
{
|
||||||
size_t length = 0;
|
size_t length = 0;
|
||||||
unsigned char c = text[pos];
|
unsigned char c = seq[0];
|
||||||
if (c < 0x80) { // 0x00-0x7F
|
if (c < 0x80) { // 0x00-0x7F
|
||||||
// is ASCII letter
|
// is ASCII letter
|
||||||
length++;
|
length++;
|
||||||
@ -876,8 +881,8 @@ size_t get_utf8_sequence_length(const std::string& text, size_t pos)
|
|||||||
// pos is in the middle of a utf-8 sequence. Add the utf-8 trailer bytes.
|
// pos is in the middle of a utf-8 sequence. Add the utf-8 trailer bytes.
|
||||||
else if (c < 0xC0) { // 0x80-0xBF
|
else if (c < 0xC0) { // 0x80-0xBF
|
||||||
length++;
|
length++;
|
||||||
while (pos + length < text.size()) {
|
while (length < size) {
|
||||||
c = text[pos + length];
|
c = seq[length];
|
||||||
if (c < 0x80 || c >= 0xC0) {
|
if (c < 0x80 || c >= 0xC0) {
|
||||||
break; // prevent overrun
|
break; // prevent overrun
|
||||||
}
|
}
|
||||||
@ -888,36 +893,36 @@ size_t get_utf8_sequence_length(const std::string& text, size_t pos)
|
|||||||
// The number of one bits above the topmost zero bit indicates the number of bytes (including this one) in the whole sequence.
|
// The number of one bits above the topmost zero bit indicates the number of bytes (including this one) in the whole sequence.
|
||||||
else if (c < 0xE0) { // 0xC0-0xDF
|
else if (c < 0xE0) { // 0xC0-0xDF
|
||||||
// add a utf-8 sequence (2 bytes)
|
// add a utf-8 sequence (2 bytes)
|
||||||
if (pos + 2 > text.size()) {
|
if (2 > size) {
|
||||||
return text.size() - pos; // prevent overrun
|
return size; // prevent overrun
|
||||||
}
|
}
|
||||||
length += 2;
|
length += 2;
|
||||||
}
|
}
|
||||||
else if (c < 0xF0) { // 0xE0-0xEF
|
else if (c < 0xF0) { // 0xE0-0xEF
|
||||||
// add a utf-8 sequence (3 bytes)
|
// add a utf-8 sequence (3 bytes)
|
||||||
if (pos + 3 > text.size()) {
|
if (3 > size) {
|
||||||
return text.size() - pos; // prevent overrun
|
return size; // prevent overrun
|
||||||
}
|
}
|
||||||
length += 3;
|
length += 3;
|
||||||
}
|
}
|
||||||
else if (c < 0xF8) { // 0xF0-0xF7
|
else if (c < 0xF8) { // 0xF0-0xF7
|
||||||
// add a utf-8 sequence (4 bytes)
|
// add a utf-8 sequence (4 bytes)
|
||||||
if (pos + 4 > text.size()) {
|
if (4 > size) {
|
||||||
return text.size() - pos; // prevent overrun
|
return size; // prevent overrun
|
||||||
}
|
}
|
||||||
length += 4;
|
length += 4;
|
||||||
}
|
}
|
||||||
else if (c < 0xFC) { // 0xF8-0xFB
|
else if (c < 0xFC) { // 0xF8-0xFB
|
||||||
// add a utf-8 sequence (5 bytes)
|
// add a utf-8 sequence (5 bytes)
|
||||||
if (pos + 5 > text.size()) {
|
if (5 > size) {
|
||||||
return text.size() - pos; // prevent overrun
|
return size; // prevent overrun
|
||||||
}
|
}
|
||||||
length += 5;
|
length += 5;
|
||||||
}
|
}
|
||||||
else if (c < 0xFE) { // 0xFC-0xFD
|
else if (c < 0xFE) { // 0xFC-0xFD
|
||||||
// add a utf-8 sequence (6 bytes)
|
// add a utf-8 sequence (6 bytes)
|
||||||
if (pos + 6 > text.size()) {
|
if (6 > size) {
|
||||||
return text.size() - pos; // prevent overrun
|
return size; // prevent overrun
|
||||||
}
|
}
|
||||||
length += 6;
|
length += 6;
|
||||||
}
|
}
|
||||||
|
@ -291,48 +291,58 @@ InfoDialog::InfoDialog(wxWindow* parent, const wxString &title, const wxString&
|
|||||||
finalize();
|
finalize();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString get_wraped_wxString(const wxString& text_in, size_t line_len /*=80*/)
|
wxString get_wraped_wxString(const wxString& in, size_t line_len /*=80*/)
|
||||||
{
|
{
|
||||||
#ifdef __WXMSW__
|
wxString out;
|
||||||
static constexpr const char slash = '\\';
|
|
||||||
|
for (size_t i = 0; i < in.size();) {
|
||||||
|
// Overwrite the character (space or newline) starting at ibreak?
|
||||||
|
bool overwrite = false;
|
||||||
|
#if wxUSE_UNICODE_WCHAR
|
||||||
|
// On Windows, most likely the internal representation of wxString is wide char.
|
||||||
|
size_t end = std::min(in.size(), i + line_len);
|
||||||
|
size_t ibreak = end;
|
||||||
|
for (size_t j = i; j < end; ++ j) {
|
||||||
|
if (bool newline = in[j] == '\n'; in[j] == ' ' || in[j] == '\t' || newline) {
|
||||||
|
ibreak = j;
|
||||||
|
overwrite = true;
|
||||||
|
if (newline)
|
||||||
|
break;
|
||||||
|
} else if (in[j] == '/' || in[j] == '\\')
|
||||||
|
ibreak = j + 1;
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
static constexpr const char slash = '/';
|
// UTF8 representation of wxString.
|
||||||
|
// Where to break the line, index of character at the start of a UTF-8 sequence.
|
||||||
|
size_t ibreak = size_t(-1);
|
||||||
|
// Overwrite the character at ibreak (it is a whitespace) or not?
|
||||||
|
for (size_t cnt = 0, j = i; j < in.size();) {
|
||||||
|
if (bool newline = in[j] == '\n'; in[j] == ' ' || in[j] == '\t' || newline) {
|
||||||
|
// Overwrite the whitespace.
|
||||||
|
ibreak = j ++;
|
||||||
|
overwrite = true;
|
||||||
|
if (newline)
|
||||||
|
break;
|
||||||
|
} else if (in[j] == '/') {
|
||||||
|
// Insert after the slash.
|
||||||
|
ibreak = ++ j;
|
||||||
|
} else
|
||||||
|
j += get_utf8_sequence_length(in.c_str() + j, in.size() - j);
|
||||||
|
if (++ cnt == line_len) {
|
||||||
|
if (ibreak == size_t(-1))
|
||||||
|
ibreak = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
static constexpr const char space = ' ';
|
out.append(in.begin() + i, in.begin() + ibreak);
|
||||||
static constexpr const char new_line = '\n';
|
out.append('\n');
|
||||||
|
i = ibreak;
|
||||||
|
if (overwrite)
|
||||||
|
++ i;
|
||||||
|
}
|
||||||
|
|
||||||
wxString text = text_in;
|
return out;
|
||||||
|
|
||||||
size_t idx = 0;
|
|
||||||
size_t cur_len = 0;
|
|
||||||
size_t text_len = text.size();
|
|
||||||
|
|
||||||
for (size_t i = 0; i < text_len; ++ i) {
|
|
||||||
if (text[i] == new_line) {
|
|
||||||
idx = i;
|
|
||||||
cur_len = 0;
|
|
||||||
} else {
|
|
||||||
++ cur_len;
|
|
||||||
if (text[i] == space || text[i] == slash)
|
|
||||||
idx = i;
|
|
||||||
if (cur_len >= line_len) {
|
|
||||||
cur_len = i - idx;
|
|
||||||
if (cur_len >= line_len) {
|
|
||||||
text.insert(++i, 1, new_line);
|
|
||||||
idx = i;
|
|
||||||
cur_len = 0;
|
|
||||||
}
|
|
||||||
else if (text[idx] == slash) {
|
|
||||||
text.insert(++idx, 1, new_line);
|
|
||||||
++text_len;
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
else // space
|
|
||||||
text[idx] = new_line;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return text;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user