229 lines
4.7 KiB
C++
229 lines
4.7 KiB
C++
/*============================================================================
|
|
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(
|
|
const std::string& 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(const std::string& 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(const std::string& keyword)
|
|
{
|
|
File << "\\" << keyword;
|
|
}
|
|
|
|
void cmWIXRichTextFormatWriter::NewControlWord(const std::string& 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 ");
|
|
}
|