123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186 |
- /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
- file Copyright.txt or https://cmake.org/licensing for details. */
- #include "cmWIXRichTextFormatWriter.h"
- #include "cmVersion.h"
- cmWIXRichTextFormatWriter::cmWIXRichTextFormatWriter(
- std::string const& filename)
- : File(filename.c_str(), std::ios::binary)
- {
- StartGroup();
- WriteHeader();
- WriteDocumentPrefix();
- }
- cmWIXRichTextFormatWriter::~cmWIXRichTextFormatWriter()
- {
- EndGroup();
- /* I haven't seen this in the RTF spec but
- * wordpad terminates its RTF like this */
- File << "\r\n";
- File.put(0);
- }
- void cmWIXRichTextFormatWriter::AddText(std::string const& text)
- {
- typedef unsigned char rtf_byte_t;
- for (size_t i = 0; i < text.size(); ++i) {
- rtf_byte_t c = rtf_byte_t(text[i]);
- switch (c) {
- case '\\':
- File << "\\\\";
- break;
- case '{':
- File << "\\{";
- break;
- case '}':
- File << "\\}";
- break;
- case '\n':
- File << "\\par\r\n";
- break;
- case '\r':
- continue;
- default: {
- if (c <= 0x7F) {
- File << c;
- } else {
- 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;
- }
- }
- }
- void cmWIXRichTextFormatWriter::WriteHeader()
- {
- ControlWord("rtf1");
- ControlWord("ansi");
- ControlWord("ansicpg1252");
- ControlWord("deff0");
- ControlWord("deflang1031");
- WriteFontTable();
- WriteColorTable();
- WriteGenerator();
- }
- void cmWIXRichTextFormatWriter::WriteFontTable()
- {
- StartGroup();
- ControlWord("fonttbl");
- StartGroup();
- ControlWord("f0");
- ControlWord("fswiss");
- ControlWord("fcharset0 Arial;");
- EndGroup();
- 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();
- NewControlWord("generator");
- File << " CPack WiX Generator (" << cmVersion::GetCMakeVersion() << ");";
- EndGroup();
- }
- void cmWIXRichTextFormatWriter::WriteDocumentPrefix()
- {
- ControlWord("viewkind4");
- ControlWord("uc1");
- ControlWord("pard");
- ControlWord("f0");
- ControlWord("fs20");
- }
- void cmWIXRichTextFormatWriter::ControlWord(std::string const& keyword)
- {
- File << "\\" << keyword;
- }
- void cmWIXRichTextFormatWriter::NewControlWord(std::string const& keyword)
- {
- File << "\\*\\" << keyword;
- }
- void cmWIXRichTextFormatWriter::StartGroup()
- {
- File.put('{');
- }
- 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 ");
- }
|