diff --git a/include/tvision/scrncell.h b/include/tvision/scrncell.h index d87e92ec..b9efd959 100644 --- a/include/tvision/scrncell.h +++ b/include/tvision/scrncell.h @@ -176,12 +176,44 @@ struct TScreenCellA : trivially_convertible }; -struct TCellChar : trivially_convertible +struct alignas(4) TCellChar { - uint8_t bytes[8]; + uint8_t bytes[12]; - using trivially_convertible::trivially_convertible; + TCellChar() = default; + + TCellChar(uint64_t ch) + { + *this = ch; + } + + TCellChar& operator=(uint64_t ch) + { + memset(this, 0, sizeof(*this)); + memcpy(bytes, &ch, std::min(sizeof(bytes), sizeof(ch))); + return *this; + } + + bool operator==(TCellChar other) const + { + return memcmp(bytes, other.bytes, sizeof(bytes)) == 0; + } + + bool operator!=(TCellChar other) const + { + return !(*this == other); + } + + uint8_t& operator[](size_t i) + { + return bytes[i]; + } + + const uint8_t& operator[](size_t i) const + { + return bytes[i]; + } void append(TStringView text) { @@ -204,7 +236,7 @@ struct TCellChar : trivially_convertible static constexpr void check_assumptions() { - check_trivial(); + static_assert(std::is_trivial()); } }; diff --git a/source/platform/buffdisp.cpp b/source/platform/buffdisp.cpp index 4887aad8..b56b3201 100644 --- a/source/platform/buffdisp.cpp +++ b/source/platform/buffdisp.cpp @@ -171,11 +171,13 @@ void BufferedDisplay::onScreenResize() void BufferedDisplay::ensurePrintable(BufferCell &cell) const { auto &ch = cell.Char; - if (ch == '\0') - ch = ' '; - else if (ch < ' ' || (0x7F <= ch && ch < 0x100)) { - // Translate from codepage as fallback. - ch = CpTranslator::toUtf8Int(ch); + if (!ch[1]) /* size 1 */ { + auto &c = ch[0]; + if (c == '\0') + c = ' '; + else if (c < ' ' || 0x7F <= c) + // Translate from codepage as fallback. + ch = CpTranslator::toUtf8Int(c); } else if (ch == TScreenCell::wideCharTrail) { ch = widePlaceholder; cell.extraWidth = 0;