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_editeng.hxx" 30 31 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */ 32 #include <osl/endian.h> 33 #include <tools/cachestr.hxx> 34 #include <vcl/graph.hxx> 35 #include <vcl/svapp.hxx> 36 #include <svtools/rtfkeywd.hxx> 37 #include <svtools/rtftoken.h> 38 #include <svtools/filter.hxx> 39 40 #include <editeng/svxrtf.hxx> 41 42 using namespace ::rtl; 43 44 #ifndef DBG_UTIL 45 #undef DEBUG_JP 46 #endif 47 48 #ifdef DEBUG_JP 49 50 #include <tools/fsys.hxx> 51 52 class GrfWindow : public WorkWindow 53 { 54 Graphic aGrf; 55 public: 56 GrfWindow( const Graphic& rGrf ); 57 virtual void Paint( const Rectangle& rRect ); 58 }; 59 60 GrfWindow::GrfWindow( const Graphic& rGrf ) 61 : WorkWindow( NULL ), 62 aGrf( rGrf ) 63 { 64 SetPosSizePixel( Point( 100, 0 ), Size( 300, 300 )); 65 Show(); 66 Invalidate(); 67 Update(); 68 } 69 70 void GrfWindow::Paint( const Rectangle& ) 71 { 72 aGrf.Draw( this, Point(0,0), GetSizePixel() ); 73 } 74 #endif 75 76 static sal_uInt8 __FAR_DATA aPal1[ 2 * 4 ] = { 77 0x00, 0x00, 0x00, 0x00, // Schwarz 78 0xFF, 0xFF, 0xFF, 0x00 // Weiss 79 }; 80 81 static sal_uInt8 __FAR_DATA aPal4[ 16 * 4 ] = { 82 0x00, 0x00, 0x00, 0x00, 83 0x80, 0x00, 0x00, 0x00, 84 0x00, 0x80, 0x00, 0x00, 85 0x80, 0x80, 0x00, 0x00, 86 0x00, 0x00, 0x80, 0x00, 87 0x80, 0x00, 0x80, 0x00, 88 0x00, 0x80, 0x80, 0x00, 89 0x80, 0x80, 0x80, 0x00, 90 0xC0, 0xC0, 0xC0, 0x00, 91 0xFF, 0x00, 0x00, 0x00, 92 0x00, 0xFF, 0x00, 0x00, 93 0xFF, 0xFF, 0x00, 0x00, 94 0x00, 0x00, 0xFF, 0x00, 95 0xFF, 0x00, 0xFF, 0x00, 96 0x00, 0xFF, 0xFF, 0x00, 97 0xFF, 0xFF, 0xFF, 0x00 98 }; 99 100 static sal_uInt8 __FAR_DATA aPal8[ 256 * 4 ] = 101 { 102 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00, 103 0x80, 0x92, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x80, 0x00, 0xAA, 0x00, 104 0x00, 0x92, 0xAA, 0x00, 0xC1, 0xC1, 0xC1, 0x00, 0xC9, 0xC9, 0xC9, 0x00, 105 0xAA, 0xDB, 0xFF, 0x00, 0x00, 0x49, 0xAA, 0x00, 0x00, 0x49, 0xFF, 0x00, 106 0x00, 0x6D, 0x00, 0x00, 0x00, 0x6D, 0x55, 0x00, 0x00, 0x6D, 0xAA, 0x00, 107 0x00, 0x6D, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x92, 0x55, 0x00, 108 0x00, 0x24, 0xAA, 0x00, 0x00, 0x92, 0xFF, 0x00, 0x00, 0xB6, 0x00, 0x00, 109 0x00, 0xB6, 0x55, 0x00, 0x00, 0xB6, 0xAA, 0x00, 0x00, 0xB6, 0xFF, 0x00, 110 0x00, 0xDB, 0x00, 0x00, 0x00, 0xDB, 0x55, 0x00, 0x00, 0xDB, 0xAA, 0x00, 111 0x00, 0xDB, 0xFF, 0x00, 0xFF, 0xDB, 0xAA, 0x00, 0x00, 0xFF, 0x55, 0x00, 112 0x00, 0xFF, 0xAA, 0x00, 0xFF, 0xFF, 0xAA, 0x00, 0x2B, 0x00, 0x00, 0x00, 113 0x2B, 0x00, 0x55, 0x00, 0x2B, 0x00, 0xAA, 0x00, 0x2B, 0x00, 0xFF, 0x00, 114 0x2B, 0x24, 0x00, 0x00, 0x2B, 0x24, 0x55, 0x00, 0x2B, 0x24, 0xAA, 0x00, 115 0x2B, 0x24, 0xFF, 0x00, 0x2B, 0x49, 0x00, 0x00, 0x2B, 0x49, 0x55, 0x00, 116 0x2B, 0x49, 0xAA, 0x00, 0x2B, 0x49, 0xFF, 0x00, 0x2B, 0x6D, 0x00, 0x00, 117 0x2B, 0x6D, 0x55, 0x00, 0x2B, 0x6D, 0xAA, 0x00, 0x2B, 0x6D, 0xFF, 0x00, 118 0x2B, 0x92, 0x00, 0x00, 0x2B, 0x92, 0x55, 0x00, 0x2B, 0x92, 0xAA, 0x00, 119 0x2B, 0x92, 0xFF, 0x00, 0x2B, 0xB6, 0x00, 0x00, 0x2B, 0xB6, 0x55, 0x00, 120 0x2B, 0xB6, 0xAA, 0x00, 0x2B, 0xB6, 0xFF, 0x00, 0x2B, 0xDB, 0x00, 0x00, 121 0x2B, 0xDB, 0x55, 0x00, 0x2B, 0xDB, 0xAA, 0x00, 0x2B, 0xDB, 0xFF, 0x00, 122 0x2B, 0xFF, 0x00, 0x00, 0x2B, 0xFF, 0x55, 0x00, 0x2B, 0xFF, 0xAA, 0x00, 123 0x2B, 0xFF, 0xFF, 0x00, 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x55, 0x00, 124 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xFF, 0x00, 0x55, 0x24, 0x00, 0x00, 125 0x55, 0x24, 0x55, 0x00, 0x55, 0x24, 0xAA, 0x00, 0x55, 0x24, 0xFF, 0x00, 126 0x55, 0x49, 0x00, 0x00, 0x55, 0x49, 0x55, 0x00, 0x55, 0x49, 0xAA, 0x00, 127 0x55, 0x49, 0xFF, 0x00, 0x55, 0x6D, 0x00, 0x00, 0x55, 0x6D, 0x55, 0x00, 128 0x55, 0x6D, 0xAA, 0x00, 0x55, 0x6D, 0xFF, 0x00, 0x55, 0x92, 0x00, 0x00, 129 0x55, 0x92, 0x55, 0x00, 0x55, 0x92, 0xAA, 0x00, 0x55, 0x92, 0xFF, 0x00, 130 0x55, 0xB6, 0x00, 0x00, 0x55, 0xB6, 0x55, 0x00, 0x55, 0xB6, 0xAA, 0x00, 131 0x55, 0xB6, 0xFF, 0x00, 0x55, 0xDB, 0x00, 0x00, 0x55, 0xDB, 0x55, 0x00, 132 0x55, 0xDB, 0xAA, 0x00, 0x55, 0xDB, 0xFF, 0x00, 0x55, 0xFF, 0x00, 0x00, 133 0x55, 0xFF, 0x55, 0x00, 0x55, 0xFF, 0xAA, 0x00, 0x55, 0xFF, 0xFF, 0x00, 134 0x00, 0x00, 0x55, 0x00, 0x80, 0x00, 0x55, 0x00, 0x00, 0x24, 0x55, 0x00, 135 0x80, 0x00, 0xFF, 0x00, 0x80, 0x24, 0x00, 0x00, 0x80, 0x24, 0x55, 0x00, 136 0x80, 0x24, 0xAA, 0x00, 0x80, 0x24, 0xFF, 0x00, 0x80, 0x49, 0x00, 0x00, 137 0x80, 0x49, 0x55, 0x00, 0x80, 0x49, 0xAA, 0x00, 0x80, 0x49, 0xFF, 0x00, 138 0x80, 0x6D, 0x00, 0x00, 0x80, 0x6D, 0x55, 0x00, 0x80, 0x6D, 0xAA, 0x00, 139 0x80, 0x6D, 0xFF, 0x00, 0x08, 0x08, 0x08, 0x00, 0x0F, 0x0F, 0x0F, 0x00, 140 0x17, 0x17, 0x17, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x27, 0x27, 0x27, 0x00, 141 0x2E, 0x2E, 0x2E, 0x00, 0x36, 0x36, 0x36, 0x00, 0x3E, 0x3E, 0x3E, 0x00, 142 0x46, 0x46, 0x46, 0x00, 0x4D, 0x4D, 0x4D, 0x00, 0x55, 0x55, 0x55, 0x00, 143 0x5D, 0x5D, 0x5D, 0x00, 0x64, 0x64, 0x64, 0x00, 0x6C, 0x6C, 0x6C, 0x00, 144 0x74, 0x74, 0x74, 0x00, 0x7C, 0x7C, 0x7C, 0x00, 0xFF, 0xDB, 0x00, 0x00, 145 0x8B, 0x8B, 0x8B, 0x00, 0x93, 0x93, 0x93, 0x00, 0x9B, 0x9B, 0x9B, 0x00, 146 0xFF, 0xB6, 0xFF, 0x00, 0xAA, 0xAA, 0xAA, 0x00, 0xB2, 0xB2, 0xB2, 0x00, 147 0xB9, 0xB9, 0xB9, 0x00, 0x00, 0x24, 0xFF, 0x00, 0x00, 0x49, 0x00, 0x00, 148 0xD1, 0xD1, 0xD1, 0x00, 0xD8, 0xD8, 0xD8, 0x00, 0xE0, 0xE0, 0xE0, 0x00, 149 0xE8, 0xE8, 0xE8, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0xFF, 0xB6, 0xAA, 0x00, 150 0xFF, 0xDB, 0xFF, 0x00, 0x80, 0x92, 0x55, 0x00, 0x80, 0x92, 0xAA, 0x00, 151 0x80, 0x92, 0xFF, 0x00, 0x80, 0xB6, 0x00, 0x00, 0x80, 0xB6, 0x55, 0x00, 152 0x80, 0xB6, 0xAA, 0x00, 0x80, 0xB6, 0xFF, 0x00, 0x80, 0xDB, 0x00, 0x00, 153 0x80, 0xDB, 0x55, 0x00, 0x80, 0xDB, 0xAA, 0x00, 0x80, 0xDB, 0xFF, 0x00, 154 0x80, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x55, 0x00, 0x80, 0xFF, 0xAA, 0x00, 155 0x80, 0xFF, 0xFF, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x55, 0x00, 156 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xFF, 0x00, 0xAA, 0x24, 0x00, 0x00, 157 0xAA, 0x24, 0x55, 0x00, 0xAA, 0x24, 0xAA, 0x00, 0xAA, 0x24, 0xFF, 0x00, 158 0xAA, 0x49, 0x00, 0x00, 0xAA, 0x49, 0x55, 0x00, 0xAA, 0x49, 0xAA, 0x00, 159 0xAA, 0x49, 0xFF, 0x00, 0xAA, 0x6D, 0x00, 0x00, 0xAA, 0x6D, 0x55, 0x00, 160 0xAA, 0x6D, 0xAA, 0x00, 0xAA, 0x6D, 0xFF, 0x00, 0xAA, 0x92, 0x00, 0x00, 161 0xAA, 0x92, 0x55, 0x00, 0xAA, 0x92, 0xAA, 0x00, 0xAA, 0x92, 0xFF, 0x00, 162 0xAA, 0xB6, 0x00, 0x00, 0xAA, 0xB6, 0x55, 0x00, 0xAA, 0xB6, 0xAA, 0x00, 163 0xAA, 0xB6, 0xFF, 0x00, 0xAA, 0xDB, 0x00, 0x00, 0xAA, 0xDB, 0x55, 0x00, 164 0xAA, 0xDB, 0xAA, 0x00, 0x00, 0x49, 0x55, 0x00, 0xAA, 0xFF, 0x00, 0x00, 165 0xAA, 0xFF, 0x55, 0x00, 0xAA, 0xFF, 0xAA, 0x00, 0xAA, 0xFF, 0xFF, 0x00, 166 0xD5, 0x00, 0x00, 0x00, 0xD5, 0x00, 0x55, 0x00, 0xD5, 0x00, 0xAA, 0x00, 167 0xD5, 0x00, 0xFF, 0x00, 0xD5, 0x24, 0x00, 0x00, 0xD5, 0x24, 0x55, 0x00, 168 0xD5, 0x24, 0xAA, 0x00, 0xD5, 0x24, 0xFF, 0x00, 0xD5, 0x49, 0x00, 0x00, 169 0xD5, 0x49, 0x55, 0x00, 0xD5, 0x49, 0xAA, 0x00, 0xD5, 0x49, 0xFF, 0x00, 170 0xD5, 0x6D, 0x00, 0x00, 0xD5, 0x6D, 0x55, 0x00, 0xD5, 0x6D, 0xAA, 0x00, 171 0xD5, 0x6D, 0xFF, 0x00, 0xD5, 0x92, 0x00, 0x00, 0xD5, 0x92, 0x55, 0x00, 172 0xD5, 0x92, 0xAA, 0x00, 0xD5, 0x92, 0xFF, 0x00, 0xD5, 0xB6, 0x00, 0x00, 173 0xD5, 0xB6, 0x55, 0x00, 0xD5, 0xB6, 0xAA, 0x00, 0xD5, 0xB6, 0xFF, 0x00, 174 0xD5, 0xDB, 0x00, 0x00, 0xD5, 0xDB, 0x55, 0x00, 0xD5, 0xDB, 0xAA, 0x00, 175 0xD5, 0xDB, 0xFF, 0x00, 0xD5, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x55, 0x00, 176 0xD5, 0xFF, 0xAA, 0x00, 0xD5, 0xFF, 0xFF, 0x00, 0xFF, 0xDB, 0x55, 0x00, 177 0xFF, 0x00, 0x55, 0x00, 0xFF, 0x00, 0xAA, 0x00, 0xFF, 0xFF, 0x55, 0x00, 178 0xFF, 0x24, 0x00, 0x00, 0xFF, 0x24, 0x55, 0x00, 0xFF, 0x24, 0xAA, 0x00, 179 0xFF, 0x24, 0xFF, 0x00, 0xFF, 0x49, 0x00, 0x00, 0xFF, 0x49, 0x55, 0x00, 180 0xFF, 0x49, 0xAA, 0x00, 0xFF, 0x49, 0xFF, 0x00, 0xFF, 0x6D, 0x00, 0x00, 181 0xFF, 0x6D, 0x55, 0x00, 0xFF, 0x6D, 0xAA, 0x00, 0xFF, 0x6D, 0xFF, 0x00, 182 0xFF, 0x92, 0x00, 0x00, 0xFF, 0x92, 0x55, 0x00, 0xFF, 0x92, 0xAA, 0x00, 183 0xFF, 0x92, 0xFF, 0x00, 0xFF, 0xB6, 0x00, 0x00, 0xFF, 0xB6, 0x55, 0x00, 184 0xF7, 0xF7, 0xF7, 0x00, 0xA2, 0xA2, 0xA2, 0x00, 0x83, 0x83, 0x83, 0x00, 185 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, 186 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 187 0xFF, 0xFF, 0xFF, 0x00 188 }; 189 190 191 /* */ 192 193 194 inline long SwapLong( long n ) 195 { 196 #ifndef OSL_LITENDIAN 197 return SWAPLONG( n ); 198 #else 199 return n; 200 #endif 201 } 202 203 inline short SwapShort( short n ) 204 { 205 #ifndef OSL_LITENDIAN 206 return SWAPSHORT( n ); 207 #else 208 return n; 209 #endif 210 } 211 212 213 static void WriteBMPHeader( SvStream& rStream, 214 const SvxRTFPictureType& rPicType ) 215 { 216 sal_uInt32 n4Width = rPicType.nWidth; 217 sal_uInt32 n4Height = rPicType.nHeight; 218 sal_uInt16 n4ColBits = rPicType.nBitsPerPixel; 219 220 sal_uInt16 nColors = (1 << n4ColBits); // Anzahl der Farben ( 1, 16, 256 ) 221 sal_uInt16 nWdtOut = rPicType.nWidthBytes; 222 if( !nWdtOut ) 223 nWdtOut = (sal_uInt16)((( n4Width * n4ColBits + 31 ) / 32 ) * 4 ); 224 225 long nOffset = 14 + 40; // BMP_FILE_HD_SIZ + sizeof(*pBmpInfo); 226 if( 256 >= nColors ) 227 nOffset += nColors * 4; 228 long nSize = nOffset + nWdtOut * n4Height; 229 rStream << "BM" // = "BM" 230 << SwapLong(nSize) // Filesize in Bytes 231 << SwapShort(0) // Reserviert 232 << SwapShort(0) // Reserviert 233 << SwapLong(nOffset); // Offset? 234 235 rStream << SwapLong(40) // sizeof( BmpInfo ) 236 << SwapLong(n4Width) 237 << SwapLong(n4Height) 238 << (sal_uInt16)1 239 << n4ColBits 240 << SwapLong(0) 241 << SwapLong(0) 242 << SwapLong( rPicType.nGoalWidth 243 ? rPicType.nGoalWidth * 1000L / 254L 244 : 0 ) // DPI in Pixel per Meter 245 << SwapLong( rPicType.nGoalHeight 246 ? rPicType.nGoalHeight * 1000L / 254L // dito 247 : 0 ) 248 << SwapLong(0) 249 << SwapLong(0); 250 251 252 switch( rPicType.nBitsPerPixel ) 253 { 254 case 1: rStream.Write( aPal1, sizeof( aPal1 )); break; 255 case 4: rStream.Write( aPal4, sizeof( aPal4 )); break; 256 case 8: rStream.Write( aPal8, sizeof( aPal8 )); break; 257 } 258 } 259 260 /* */ 261 262 // wandel die ASCII-HexCodes in binaere Zeichen um. Werden 263 // ungueltige Daten gefunden (Zeichen ausser 0-9|a-f|A-F, so 264 // wird USHRT_MAX returnt, ansonsten die Anzahl der umgewandelten Ze. 265 xub_StrLen SvxRTFParser::HexToBin( String& rToken ) 266 { 267 // dann mache aus den Hex-Werten mal "Binare Daten" 268 // (missbrauche den String als temp Buffer) 269 if( rToken.Len() & 1 ) // ungerade Anzahl, mit 0 auffuellen 270 rToken += '0'; 271 272 xub_StrLen n, nLen; 273 sal_Unicode nVal; 274 sal_Bool bValidData = sal_True; 275 const sal_Unicode* pStr = rToken.GetBufferAccess(); 276 sal_Char* pData = (sal_Char*)pStr; 277 for( n = 0, nLen = rToken.Len(); n < nLen; ++n, ++pStr ) 278 { 279 if( ((nVal = *pStr) >= '0') && ( nVal <= '9') ) 280 nVal -= '0'; 281 else if( (nVal >= 'A') && (nVal <= 'F') ) 282 nVal -= 'A' - 10; 283 else if( (nVal >= 'a') && (nVal <= 'f') ) 284 nVal -= 'a' - 10; 285 else 286 { 287 DBG_ASSERT( !this, "ungueltiger Hex-Wert" ); 288 bValidData = sal_False; 289 break; 290 } 291 292 if( n & 1 ) 293 *(pData++) |= nVal & 0x0f; 294 else 295 *(pData) = sal::static_int_cast< char >( ( nVal << 4 ) & 0xf0 ); 296 } 297 // the len div 2, because 2 character are one byte 298 return bValidData ? nLen / 2 : STRING_NOTFOUND; 299 } 300 301 sal_Bool SvxRTFParser::ReadBmpData( Graphic& rGrf, SvxRTFPictureType& rPicType ) 302 { 303 // die alten Daten loeschen 304 rGrf.Clear(); 305 // sal_uInt32 nBmpSize = 0; 306 307 rtl_TextEncoding eOldEnc = GetSrcEncoding(); 308 SetSrcEncoding( RTL_TEXTENCODING_MS_1252 ); 309 310 const sal_Char* pFilterNm = 0; 311 SvCacheStream* pTmpFile = 0; 312 313 int nToken = 0; 314 bool bValidBmp = true, bFirstTextToken = true; 315 int _nOpenBrakets = 1, // die erste wurde schon vorher erkannt !! 316 nValidDataBraket = 1; 317 318 if( RTF_SHPPICT == GetStackPtr(0)->nTokenId ) 319 ++nValidDataBraket; 320 OUString sShapePropertyName, sShapePropertyValue; 321 int nShapePropertyBracket = -1; 322 while( _nOpenBrakets && IsParserWorking() && bValidBmp ) 323 { 324 nToken = GetNextToken(); 325 sal_uInt16 nVal = sal_uInt16( nTokenValue ); 326 switch( nToken ) 327 { 328 case '}': 329 --_nOpenBrakets; 330 if( nShapePropertyBracket > 0 && nShapePropertyBracket > _nOpenBrakets ) 331 { 332 nShapePropertyBracket = -1; 333 if( sShapePropertyName.getLength() ) 334 { 335 rPicType.aPropertyPairs.push_back( ::std::pair< OUString, OUString >( sShapePropertyName, sShapePropertyValue ) ); 336 sShapePropertyName = sShapePropertyValue = ::rtl::OUString(); 337 } 338 } 339 break; 340 case '{': 341 { 342 if( RTF_IGNOREFLAG != GetNextToken() ) 343 nToken = SkipToken( -1 ); 344 else if( RTF_UNKNOWNCONTROL != GetNextToken() ) 345 nToken = SkipToken( -2 ); 346 else 347 { 348 // gleich herausfiltern 349 ReadUnknownData(); 350 nToken = GetNextToken(); 351 if( '}' != nToken ) 352 eState = SVPAR_ERROR; 353 break; 354 } 355 ++_nOpenBrakets; 356 } 357 break; 358 359 case RTF_MACPICT: 360 { 361 rPicType.eStyle = SvxRTFPictureType::MAC_QUICKDRAW; 362 // Mac-Pict bekommt einen leeren Header voran 363 pTmpFile = new SvCacheStream; 364 ByteString aStr; 365 aStr.Fill( 512, '\0' ); 366 pTmpFile->Write( aStr.GetBuffer(), aStr.Len() ); 367 pFilterNm = "PCT"; 368 } 369 break; 370 371 case RTF_EMFBLIP: 372 case RTF_WMETAFILE: 373 case RTF_PNGBLIP: 374 case RTF_JPEGBLIP: 375 case RTF_WBITMAP: 376 case RTF_OSMETAFILE: 377 case RTF_DIBITMAP: 378 { 379 switch( nToken ) 380 { 381 case RTF_EMFBLIP: 382 rPicType.eStyle = SvxRTFPictureType::ENHANCED_MF; 383 pFilterNm = "EMF"; 384 break; 385 case RTF_WMETAFILE: 386 rPicType.eStyle = SvxRTFPictureType::WIN_METAFILE; 387 pFilterNm = "WMF"; 388 break; 389 case RTF_PNGBLIP: 390 rPicType.eStyle = SvxRTFPictureType::RTF_PNG; 391 pFilterNm = "PNG"; 392 break; 393 case RTF_JPEGBLIP: 394 rPicType.eStyle = SvxRTFPictureType::RTF_JPG; 395 pFilterNm = "JPG"; 396 break; 397 398 case RTF_WBITMAP: 399 rPicType.eStyle = SvxRTFPictureType::RTF_BITMAP; 400 break; 401 case RTF_OSMETAFILE: 402 rPicType.eStyle = SvxRTFPictureType::OS2_METAFILE; 403 break; 404 case RTF_DIBITMAP: 405 rPicType.eStyle = SvxRTFPictureType::RTF_DI_BMP; 406 break; 407 } 408 409 rPicType.nType = nVal; 410 pTmpFile = new SvCacheStream; 411 } 412 break; 413 414 case RTF_PICW: rPicType.nWidth = nVal; break; 415 case RTF_PICH: rPicType.nHeight = nVal; break; 416 case RTF_WBMBITSPIXEL: rPicType.nBitsPerPixel = nVal; break; 417 case RTF_WBMPLANES: rPicType.nPlanes = nVal; break; 418 case RTF_WBMWIDTHBYTES: rPicType.nWidthBytes = nVal; break; 419 case RTF_PICWGOAL: rPicType.nGoalWidth = nVal; break; 420 case RTF_PICHGOAL: rPicType.nGoalHeight = nVal; break; 421 case RTF_BIN: 422 rPicType.nMode = SvxRTFPictureType::BINARY_MODE; 423 rPicType.uPicLen = nTokenValue; 424 if (rPicType.uPicLen) 425 { 426 sal_uInt32 nPos = rStrm.Tell(); 427 nPos = nPos; 428 rStrm.SeekRel(-1); 429 sal_uInt8 aData[4096]; 430 sal_uInt32 nSize = sizeof(aData); 431 432 while (rPicType.uPicLen > 0) 433 { 434 if (rPicType.uPicLen < nSize) 435 nSize = rPicType.uPicLen; 436 437 rStrm.Read(aData, nSize); 438 pTmpFile->Write(aData, nSize); 439 rPicType.uPicLen -= nSize; 440 } 441 nNextCh = GetNextChar(); 442 bValidBmp = !pTmpFile->GetError(); 443 nPos = rStrm.Tell(); 444 nPos = nPos; 445 } 446 break; 447 case RTF_PICSCALEX: rPicType.nScalX = nVal; break; 448 case RTF_PICSCALEY: rPicType.nScalY = nVal; break; 449 case RTF_PICSCALED: break; 450 451 case RTF_PICCROPT: rPicType.nCropT = (short)nTokenValue; break; 452 case RTF_PICCROPB: rPicType.nCropB = (short)nTokenValue; break; 453 case RTF_PICCROPL: rPicType.nCropL = (short)nTokenValue; break; 454 case RTF_PICCROPR: rPicType.nCropR = (short)nTokenValue; break; 455 case RTF_SP: 456 //read pairs of {\sn Name}{\sv Value} 457 nShapePropertyBracket = _nOpenBrakets; 458 break; 459 case RTF_SN: 460 nToken = GetNextToken(); 461 if( nToken != '}' ) 462 sShapePropertyName = aToken; 463 else 464 nToken = SkipToken( -1 ); 465 break; 466 case RTF_SV: 467 nToken = GetNextToken(); 468 if( nToken != '}' ) 469 sShapePropertyValue = aToken; 470 else 471 nToken = SkipToken( -1 ); 472 break; 473 case RTF_TEXTTOKEN: 474 // JP 26.06.98: Bug #51719# - nur TextToken auf 1. Ebene 475 // auswerten. Alle anderen sind irgendwelche 476 // nicht auszuwertende Daten 477 if( nValidDataBraket != _nOpenBrakets ) 478 break; 479 480 if( bFirstTextToken ) 481 { 482 switch( rPicType.eStyle ) 483 { 484 case SvxRTFPictureType::RTF_BITMAP: 485 // erstmal die Header und Info-Struktur schreiben 486 if( pTmpFile ) 487 ::WriteBMPHeader( *pTmpFile, rPicType ); 488 break; 489 default: 490 break; 491 } 492 bFirstTextToken = sal_False; 493 } 494 495 if( pTmpFile && SvxRTFPictureType::HEX_MODE == rPicType.nMode ) 496 { 497 xub_StrLen nTokenLen = HexToBin( aToken ); 498 if( STRING_NOTFOUND == nTokenLen ) 499 bValidBmp = sal_False; 500 else 501 { 502 pTmpFile->Write( (sal_Char*)aToken.GetBuffer(), 503 nTokenLen ); 504 bValidBmp = 0 == pTmpFile->GetError(); 505 } 506 } 507 break; 508 } 509 } 510 511 if (pTmpFile) 512 { 513 //#i20775# 514 if (pTmpFile->Tell() == 0) 515 bValidBmp = false; 516 517 if( bValidBmp ) 518 { 519 GraphicFilter* pGF = GraphicFilter::GetGraphicFilter(); 520 sal_uInt16 nImportFilter = GRFILTER_FORMAT_DONTKNOW; 521 522 if( pFilterNm ) 523 { 524 String sTmp; 525 for( sal_uInt16 n = pGF->GetImportFormatCount(); n; ) 526 { 527 sTmp = pGF->GetImportFormatShortName( --n ); 528 if( sTmp.EqualsAscii( pFilterNm )) 529 { 530 nImportFilter = n; 531 break; 532 } 533 } 534 } 535 536 String sTmpStr; 537 pTmpFile->Seek( STREAM_SEEK_TO_BEGIN ); 538 bValidBmp = 0 == pGF->ImportGraphic( rGrf, sTmpStr, *pTmpFile, 539 nImportFilter ); 540 } 541 delete pTmpFile; 542 } 543 544 if( !bValidBmp ) 545 { 546 rGrf.Clear(); 547 //TODO If nToken were not initialized to 0 above, it would potentially 548 // be used uninitialized here (if IsParserWorking() is false at the 549 // start of the while loop above): 550 if( '}' != nToken ) 551 SkipGroup(); 552 } 553 else 554 { 555 switch( rPicType.eStyle ) 556 { 557 //?? ENHANCED_MF, // in den Pict.Daten steht ein Enhanced-Metafile 558 case SvxRTFPictureType::RTF_PNG: 559 case SvxRTFPictureType::RTF_JPG: 560 { 561 const MapMode aMap( MAP_100TH_MM ); 562 Size aSize( rGrf.GetPrefSize() ); 563 if( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() ) 564 aSize = Application::GetDefaultDevice()->PixelToLogic( 565 aSize, aMap ); 566 else 567 aSize = OutputDevice::LogicToLogic( aSize, 568 rGrf.GetPrefMapMode(), aMap ); 569 rPicType.nWidth = sal::static_int_cast< sal_uInt16 >(aSize.Width()); 570 rPicType.nHeight = sal::static_int_cast< sal_uInt16 >( 571 aSize.Height()); 572 } 573 break; 574 default: 575 break; 576 } 577 578 #ifdef DEBUG_JP 579 new GrfWindow( rGrf ); 580 #endif 581 } 582 SetSrcEncoding( eOldEnc ); 583 584 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet 585 return bValidBmp; 586 } 587 588 /* vi:set tabstop=4 shiftwidth=4 expandtab: */ 589