diff --git a/Modules/CPackWIX.cmake b/Modules/CPackWIX.cmake index d9e0ba717..30f57c785 100644 --- a/Modules/CPackWIX.cmake +++ b/Modules/CPackWIX.cmake @@ -52,6 +52,7 @@ # # If CPACK_RESOURCE_FILE_LICENSE has an .txt extension it is implicitly # converted to RTF by the WiX Generator. +# The expected encoding of the .txt file is UTF-8. # # With CPACK_WIX_LICENSE_RTF you can override the license file used by the # WiX Generator in case CPACK_RESOURCE_FILE_LICENSE is in an unsupported diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx index 886b534de..ddc1d7138 100644 --- a/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx +++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.cxx @@ -65,7 +65,41 @@ void cmWIXRichTextFormatWriter::AddText(const std::string& text) } else { - File << "[NON-ASCII-" << int(c) << "]"; + if(c <= 0xC0) + { + EmitInvalidCodepoint(c); + } + else if(c < 0xE0 && i+1 < text.size()) + { + EmitUnicodeCodepoint( + (text[i+1] & 0x3F) | + ((c & 0x1F) << 6) + ); + i+= 1; + } + else if(c < 0xF0 && i+2 < text.size()) + { + EmitUnicodeCodepoint( + (text[i+2] & 0x3F) | + ((text[i+1] & 0x3F) << 6) | + ((c & 0xF) << 12) + ); + i += 2; + } + else if(c < 0xF8 && i+3 < text.size()) + { + EmitUnicodeCodepoint( + (text[i+3] & 0x3F) | + ((text[i+2] & 0x3F) << 6) | + ((text[i+1] & 0x3F) << 12) | + ((c & 0x7) << 18) + ); + i += 3; + } + else + { + EmitInvalidCodepoint(c); + } } } break; @@ -82,6 +116,7 @@ void cmWIXRichTextFormatWriter::WriteHeader() ControlWord("deflang1031"); WriteFontTable(); + WriteColorTable(); WriteGenerator(); } @@ -99,6 +134,22 @@ void cmWIXRichTextFormatWriter::WriteFontTable() EndGroup(); } +void cmWIXRichTextFormatWriter::WriteColorTable() +{ + StartGroup(); + ControlWord("colortbl ;"); + ControlWord("red255"); + ControlWord("green0"); + ControlWord("blue0;"); + ControlWord("red0"); + ControlWord("green255"); + ControlWord("blue0;"); + ControlWord("red0"); + ControlWord("green0"); + ControlWord("blue255;"); + EndGroup(); +} + void cmWIXRichTextFormatWriter::WriteGenerator() { StartGroup(); @@ -135,3 +186,43 @@ void cmWIXRichTextFormatWriter::EndGroup() { File.put('}'); } + +void cmWIXRichTextFormatWriter::EmitUnicodeCodepoint(int c) +{ + // Do not emit byte order mark (BOM) + if(c == 0xFEFF) + { + return; + } + else if(c <= 0xFFFF) + { + EmitUnicodeSurrogate(c); + } + else + { + c -= 0x10000; + EmitUnicodeSurrogate(((c >> 10) & 0x3FF) + 0xD800); + EmitUnicodeSurrogate((c & 0x3FF) + 0xDC00); + } +} + +void cmWIXRichTextFormatWriter::EmitUnicodeSurrogate(int c) +{ + ControlWord("u"); + if(c <= 32767) + { + File << c; + } + else + { + File << (c - 65536); + } + File << "?"; +} + +void cmWIXRichTextFormatWriter::EmitInvalidCodepoint(int c) +{ + ControlWord("cf1 "); + File << "[INVALID-BYTE-" << int(c) << "]"; + ControlWord("cf0 "); +} diff --git a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h index bb8580aa0..38e40b049 100644 --- a/Source/CPack/WiX/cmWIXRichTextFormatWriter.h +++ b/Source/CPack/WiX/cmWIXRichTextFormatWriter.h @@ -30,6 +30,7 @@ public: private: void WriteHeader(); void WriteFontTable(); + void WriteColorTable(); void WriteGenerator(); void WriteDocumentPrefix(); @@ -40,6 +41,11 @@ private: void StartGroup(); void EndGroup(); + void EmitUnicodeCodepoint(int c); + void EmitUnicodeSurrogate(int c); + + void EmitInvalidCodepoint(int c); + std::ofstream File; }; diff --git a/Tests/CPackWiXGenerator/CMakeLists.txt b/Tests/CPackWiXGenerator/CMakeLists.txt index 0b0604548..bc3322ef3 100644 --- a/Tests/CPackWiXGenerator/CMakeLists.txt +++ b/Tests/CPackWiXGenerator/CMakeLists.txt @@ -51,6 +51,8 @@ set(CPACK_PACKAGE_EXECUTABLES set(CPACK_WIX_PATCH_FILE "${CMAKE_CURRENT_SOURCE_DIR}/patch.xml") +set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license.txt") + include(CPack) cpack_add_install_type(Full DISPLAY_NAME "Everything") diff --git a/Tests/CPackWiXGenerator/license.txt b/Tests/CPackWiXGenerator/license.txt new file mode 100644 index 000000000..79427833d --- /dev/null +++ b/Tests/CPackWiXGenerator/license.txt @@ -0,0 +1,9 @@ +hello world +merhaba dünya +ハローワールド +привет мир +مرحبا العالم +你好世界 + +4-Byte sequences: + Perch (Fish) 𩶘 Elevator 𨋢!