mirror of
https://github.com/wxWidgets/wxWidgets.git
synced 2026-10-06 07:00:16 +08:00
Previously wxString::Format("%c", wxUniChar{0x1F600}) produced broken
"\uF600" under MSW because this was all that fit into a wchar_t there
which can only contain 16-bits. And using "%d" or "%x" was broken in the
same way, as wxArgNormalizer<wxUniChar> always used wx_truncate_cast()
to wchar_t which is not lossless when sizeof(wchar_t)==2.
Fix this with the following horrible/ingenuous/crazy (choose your own
adjective) hack: because we can't fit supplementary Unicode characters
into a wchar_t, don't even try doing it and instead inject the bytes
representing the character into the format string itself (suitable
padded/aligned depending on the formatting flags) and replace the
format specifier used for wxUniChar with "%.0d" and feed it 0, which
ensures that no output is produced for it.
This can be done with surprisingly little amount of changes and should
be completely transparent to any code not formatting wxUniChars outside
of the BMP -- while such code will now behave correctly, instead of
silently producing wrong output as before, under MSW too.
Note that we do this unconditionally, i.e. without preprocessor checks
for SIZEOF_WCHAR_T, even if old code worked when it was 4, because using
the same code under all platforms should make finding and fixing bugs in
it simpler and also because this code is already hairy enough to not
need any extra complications.