| /*============================================================================ |
| CMake - Cross Platform Makefile Generator |
| Copyright 2000-2012 Kitware, Inc. |
| |
| Distributed under the OSI-approved BSD License (the "License"); |
| see accompanying file Copyright.txt for details. |
| |
| This software is distributed WITHOUT ANY WARRANTY; without even the |
| implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the License for more information. |
| ============================================================================*/ |
| |
| #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 "); |
| } |