@@ -921,10 +921,10 @@ auto FTermOutput::repeatCharacter (uInt& x, uInt xmax, uInt y, const FChar_itera
921921
922922 if ( rp.data && repetition_type == Repetition::ASCII )
923923 {
924- newFontChanges (*iter);
925- charsetChanges (*iter);
924+ newFontFilter (*iter);
925+ auto ch_enc = charsetEncode (*iter);
926926 appendAttributes (*iter);
927- const auto term_ctrl = FTermcap::encodeParameter (rp, iter-> ch . unicode_data [ 0 ] , repetitions);
927+ const auto term_ctrl = FTermcap::encodeParameter (rp, ch_enc , repetitions);
928928 appendOutputBuffer (FTermControl{term_ctrl});
929929 term_pos->x_ref () += static_cast <int >(repetitions);
930930 }
@@ -1194,53 +1194,51 @@ inline void FTermOutput::markAsPrinted (uInt from, uInt to, uInt y) const noexce
11941194}
11951195
11961196// ----------------------------------------------------------------------
1197- inline void FTermOutput::newFontChanges (FChar& next_char) const
1197+ inline void FTermOutput::newFontFilter (FChar& next_char) const noexcept
11981198{
11991199 // NewFont special cases
12001200 if ( ! internal::var::is_new_font )
12011201 return ;
12021202
1203- if ( next_char.ch .unicode_data [0 ] == UniChar::LowerHalfBlock )
1203+ auto & first_char = next_char.ch .unicode_data [0 ];
1204+
1205+ if ( first_char == UniChar::LowerHalfBlock )
12041206 {
1205- next_char. ch . unicode_data [ 0 ] = wchar_t (UniChar::UpperHalfBlock);
1207+ first_char = wchar_t (UniChar::UpperHalfBlock);
12061208 next_char.setBit (FAttribute::set::reverse);
1209+ return ;
12071210 }
1208- else if ( isReverseNewFontchar (next_char.ch .unicode_data [0 ]) )
1211+
1212+ if ( isReverseNewFontchar (first_char) )
12091213 next_char.setBit (FAttribute::set::reverse); // Show in reverse video
12101214}
12111215
12121216// ----------------------------------------------------------------------
1213- inline void FTermOutput::charsetChanges (FChar& next_char) const
1217+ inline auto FTermOutput::charsetEncode (FChar& next_char) const noexcept -> uChar
12141218{
1215- if ( internal::terminal::encoding == Encoding::UTF8 )
1216- return ;
1217-
1218- std::memcpy ( next_char.encoded_char .data (),
1219- next_char.ch .data (),
1220- sizeof (wchar_t ) * UNICODE_MAX );
1221-
12221219 const auto & ch = next_char.ch .unicode_data [0 ];
1223- const auto & ch_enc = FTerm::charEncode (ch);
12241220
1225- if ( ch_enc == ch )
1226- return ;
1221+ if ( internal::terminal::encoding == Encoding:: UTF8 )
1222+ return uChar (ch & 0xff ) ;
12271223
1228- auto & first_enc_char = next_char. encoded_char . unicode_data [ 0 ] ;
1224+ const auto ch_enc = FTerm::charEncode (ch) ;
12291225
1230- if ( ch_enc == 0 )
1231- {
1232- first_enc_char = wchar_t (FTerm::charEncode (ch, Encoding::ASCII ));
1233- return ;
1234- }
1226+ if ( uChar (ch_enc & 0xff ) == ch )
1227+ return ch_enc;
12351228
1236- first_enc_char = ch_enc;
1229+ if ( ch_enc == 0 )
1230+ return FTerm::charEncode (ch, Encoding::ASCII );
12371231
12381232 if ( internal::terminal::encoding == Encoding::VT100 )
1233+ {
12391234 next_char.attr .data |= FAttribute::set::alt_charset; // Set alt charset
1240- else if ( internal::terminal::encoding == Encoding::PC )
1235+ return ch_enc;
1236+ }
1237+
1238+ if ( internal::terminal::encoding == Encoding::PC )
12411239 {
12421240 if ( ch_enc >= 0x20 )
1243- return ;
1241+ return ch_enc ;
12441242
12451243 // Character 0x00..0x1f
12461244 next_char.attr .data |= FAttribute::set::pc_charset; // Set pc charset
@@ -1249,16 +1247,18 @@ inline void FTermOutput::charsetChanges (FChar& next_char) const
12491247 const auto is_xterm = fterm_data->isTermType (FTermType::xterm);
12501248
12511249 if ( is_putty || ! is_xterm )
1252- return ;
1250+ return ch_enc ;
12531251
12541252 if ( FTerm::hasUTF8 () )
1255- first_enc_char = int ( FTerm::charEncode (ch, Encoding::ASCII ) );
1253+ return FTerm::charEncode (ch, Encoding::ASCII );
12561254 else
12571255 {
1258- first_enc_char += 0x5f ;
12591256 next_char.attr .data |= FAttribute::set::alt_charset; // Set alt charset
1257+ return ch_enc + 0x5f ;
12601258 }
12611259 }
1260+
1261+ return ch_enc;
12621262}
12631263
12641264// ----------------------------------------------------------------------
@@ -1286,13 +1286,18 @@ inline void FTermOutput::appendCharacter_n (const FChar_iterator& next_char_iter
12861286// ----------------------------------------------------------------------
12871287inline void FTermOutput::appendChar (FChar& next_char)
12881288{
1289- newFontChanges (next_char);
1290- charsetChanges (next_char);
1291- appendAttributes (next_char);
1292- characterFilter (next_char);
1293-
12941289 if ( internal::terminal::encoding == Encoding::UTF8 )
12951290 {
1291+ newFontFilter (next_char);
1292+ characterFilter (next_char.ch .unicode_data [0 ]);
1293+ appendAttributes (next_char);
1294+
1295+ if ( needsInvisibleSimulation (next_char) )
1296+ {
1297+ appendOutputBuffer (' ' ); // Simulate invisible character
1298+ return ;
1299+ }
1300+
12961301 for (const auto & ch : next_char.ch )
12971302 {
12981303 if ( ch == L' \0 ' )
@@ -1306,12 +1311,31 @@ inline void FTermOutput::appendChar (FChar& next_char)
13061311 }
13071312 else // ASCII, VT100, or PC encoding
13081313 {
1309- appendOutputBuffer ( FOutputBuffer::OutputType::String
1310- , reinterpret_cast <char *>(&next_char.encoded_char .unicode_data [0 ])
1311- , 1 );
1314+ newFontFilter (next_char);
1315+ characterFilter (next_char.ch .unicode_data [0 ]);
1316+ auto ch_enc = char (charsetEncode (next_char));
1317+ appendAttributes (next_char);
1318+
1319+ if ( needsInvisibleSimulation (next_char) )
1320+ {
1321+ appendOutputBuffer (' ' ); // Simulate invisible character
1322+ return ;
1323+ }
1324+
1325+ appendOutputBuffer (ch_enc);
13121326 }
13131327}
13141328
1329+ // ----------------------------------------------------------------------
1330+ inline auto FTermOutput::needsInvisibleSimulation (const FChar& next_char) -> bool
1331+ {
1332+ const auto & mk = TCAP (t_enter_secure_mode);
1333+ return ! mk.data && next_char.isBitSet (FAttribute::set::invisible);
1334+ // true = The next character is invisible, but this terminal does
1335+ // not support that feature. Therefore, you must simulate
1336+ // an invisible character.
1337+ }
1338+
13151339// ----------------------------------------------------------------------
13161340inline void FTermOutput::appendAttributes (FChar& next_attr)
13171341{
@@ -1391,17 +1415,16 @@ void FTermOutput::appendLowerRight (const FChar_iterator& last_char_iter)
13911415}
13921416
13931417// ----------------------------------------------------------------------
1394- inline void FTermOutput::characterFilter (FChar& next_char)
1418+ inline void FTermOutput::characterFilter (wchar_t & w_char) noexcept
13951419{
13961420 if ( ! internal::var::has_sub_map )
13971421 return ;
13981422
13991423 static const auto & sub_map = getFTerm ().getCharSubstitutionMap ();
1400- auto & first_enc_char = next_char.encoded_char .unicode_data [0 ];
1401- const auto & entry = sub_map.getMappedChar (first_enc_char);
1424+ const auto found = sub_map.getMappedChar (w_char);
14021425
1403- if ( entry )
1404- first_enc_char = entry ;
1426+ if ( found )
1427+ w_char = found ;
14051428}
14061429
14071430// ----------------------------------------------------------------------
@@ -1463,6 +1486,14 @@ inline void FTermOutput::appendOutputBuffer (const UniChar& ch)
14631486 appendOutputBuffer (wchar_t (ch));
14641487}
14651488
1489+ // ----------------------------------------------------------------------
1490+ inline void FTermOutput::appendOutputBuffer (char ch)
1491+ {
1492+ appendOutputBuffer ( FOutputBuffer::OutputType::String
1493+ , reinterpret_cast <char *>(&ch)
1494+ , 1 );
1495+ }
1496+
14661497// ----------------------------------------------------------------------
14671498inline void FTermOutput::appendOutputBuffer ( FOutputBuffer::OutputType type
14681499 , const char * data
0 commit comments