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