1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svtools.hxx" 30 #include <tools/debug.hxx> 31 #include <tools/stream.hxx> 32 #include <tools/string.hxx> 33 #include <rtl/string.hxx> 34 #include <rtl/ustrbuf.hxx> 35 #include <svtools/rtfkeywd.hxx> 36 #include <svtools/rtfout.hxx> 37 38 using namespace rtl; 39 40 #if defined(UNX) 41 const sal_Char RTFOutFuncs::sNewLine = '\012'; 42 #else 43 const sal_Char __FAR_DATA RTFOutFuncs::sNewLine[] = "\015\012"; 44 #endif 45 46 47 SvStream& RTFOutFuncs::Out_Char(SvStream& rStream, sal_Unicode c, 48 int *pUCMode, rtl_TextEncoding eDestEnc, sal_Bool bWriteHelpFile) 49 { 50 const sal_Char* pStr = 0; 51 switch (c) 52 { 53 case 0x1: 54 case 0x2: 55 // this are control character of our textattributes and will never be 56 // written 57 break; 58 case 0xA0: 59 rStream << "\\~"; 60 break; 61 case 0xAD: 62 rStream << "\\-"; 63 break; 64 case 0x2011: 65 rStream << "\\_"; 66 break; 67 case '\n': 68 pStr = OOO_STRING_SVTOOLS_RTF_LINE; 69 break; 70 case '\t': 71 pStr = OOO_STRING_SVTOOLS_RTF_TAB; 72 break; 73 default: 74 if(!bWriteHelpFile) 75 { 76 switch(c) 77 { 78 case 149: 79 pStr = OOO_STRING_SVTOOLS_RTF_BULLET; 80 break; 81 case 150: 82 pStr = OOO_STRING_SVTOOLS_RTF_ENDASH; 83 break; 84 case 151: 85 pStr = OOO_STRING_SVTOOLS_RTF_EMDASH; 86 break; 87 case 145: 88 pStr = OOO_STRING_SVTOOLS_RTF_LQUOTE; 89 break; 90 case 146: 91 pStr = OOO_STRING_SVTOOLS_RTF_RQUOTE; 92 break; 93 case 147: 94 pStr = OOO_STRING_SVTOOLS_RTF_LDBLQUOTE; 95 break; 96 case 148: 97 pStr = OOO_STRING_SVTOOLS_RTF_RDBLQUOTE; 98 break; 99 } 100 101 if (pStr) 102 break; 103 } 104 105 switch (c) 106 { 107 case '\\': 108 case '}': 109 case '{': 110 rStream << '\\' << (sal_Char)c; 111 break; 112 default: 113 if (c >= ' ' && c <= '~') 114 rStream << (sal_Char)c; 115 else 116 { 117 //If we can't convert to the dest encoding, or if 118 //its an uncommon multibyte sequence which most 119 //readers won't be able to handle correctly, then 120 //If we can't convert to the dest encoding, then 121 //export as unicode 122 OUString sBuf(&c, 1); 123 OString sConverted; 124 sal_uInt32 nFlags = 125 RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR | 126 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR; 127 bool bWriteAsUnicode = !(sBuf.convertToString(&sConverted, 128 eDestEnc, nFlags)) 129 || (RTL_TEXTENCODING_UTF8==eDestEnc); // #i43933# do not export UTF-8 chars in RTF; 130 if (bWriteAsUnicode) 131 { 132 sBuf.convertToString(&sConverted, 133 eDestEnc, OUSTRING_TO_OSTRING_CVTFLAGS); 134 } 135 const sal_Int32 nLen = sConverted.getLength(); 136 137 if (bWriteAsUnicode && pUCMode) 138 { 139 // then write as unicode - character 140 if (*pUCMode != nLen) 141 { 142 rStream << "\\uc" << ByteString::CreateFromInt32(nLen).GetBuffer() << " "; // #i47831# add an additional whitespace, so that "document whitespaces" are not ignored.; 143 *pUCMode = nLen; 144 } 145 ByteString sNo(ByteString::CreateFromInt32(c)); 146 rStream << "\\u" << sNo.GetBuffer(); 147 } 148 149 for (sal_Int32 nI = 0; nI < nLen; ++nI) 150 { 151 rStream << "\\'"; 152 Out_Hex(rStream, sConverted.getStr()[nI], 2); 153 } 154 } 155 break; 156 } 157 break; 158 } 159 160 if (pStr) 161 rStream << pStr << ' '; 162 163 return rStream; 164 } 165 166 SvStream& RTFOutFuncs::Out_String( SvStream& rStream, const String& rStr, 167 rtl_TextEncoding eDestEnc, sal_Bool bWriteHelpFile) 168 { 169 int nUCMode = 1; 170 for (xub_StrLen n = 0; n < rStr.Len(); ++n) 171 Out_Char(rStream, rStr.GetChar(n), &nUCMode, eDestEnc, bWriteHelpFile); 172 if (nUCMode != 1) 173 rStream << "\\uc1"<< " "; // #i47831# add an additional whitespace, so that "document whitespaces" are not ignored.; 174 return rStream; 175 } 176 177 SvStream& RTFOutFuncs::Out_Fontname(SvStream& rStream, const String& rStr, 178 rtl_TextEncoding eDestEnc, sal_Bool bWriteHelpFile) 179 { 180 //Fontnames in word have a quirk in that \uc and usage of ansi replacement 181 //chars after a \u don't work and in wordpad \u doesn't work, so we are 182 //left with forcing ansi characters only for fontnames 183 for (xub_StrLen n = 0; n < rStr.Len(); ++n) 184 Out_Char(rStream, rStr.GetChar(n), 0, eDestEnc, bWriteHelpFile); 185 return rStream; 186 } 187 188 SvStream& RTFOutFuncs::Out_Hex( SvStream& rStream, sal_uLong nHex, sal_uInt8 nLen ) 189 { 190 sal_Char aNToABuf[] = "0000000000000000"; 191 192 DBG_ASSERT( nLen < sizeof(aNToABuf), "zu viele Stellen" ); 193 if( nLen >= sizeof(aNToABuf) ) 194 nLen = (sizeof(aNToABuf)-1); 195 196 // Pointer an das Bufferende setzen 197 sal_Char* pStr = aNToABuf + (sizeof(aNToABuf)-1); 198 for( sal_uInt8 n = 0; n < nLen; ++n ) 199 { 200 *(--pStr) = (sal_Char)(nHex & 0xf ) + 48; 201 if( *pStr > '9' ) 202 *pStr += 39; 203 nHex >>= 4; 204 } 205 return rStream << pStr; 206 } 207 208 209 210