Update ooo320-m1
[ooovba.git] / svx / source / svrtf / rtfgrf.cxx
blob4666f53f00c03205b2956fe79277ab8d170c8973
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: rtfgrf.cxx,v $
10 * $Revision: 1.13 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
35 #include <osl/endian.h>
36 #include <tools/cachestr.hxx>
37 #include <vcl/graph.hxx>
38 #include <vcl/svapp.hxx>
39 #include <svtools/rtfkeywd.hxx>
40 #include <svtools/rtftoken.h>
41 #include <svtools/filter.hxx>
42 #include <svtools/wmf.hxx>
44 #include "impgrf.hxx"
45 #include "svxrtf.hxx"
48 #ifdef PRODUCT
49 #undef DEBUG_JP
50 #endif
52 #ifdef DEBUG_JP
54 #include <tools/fsys.hxx>
56 class GrfWindow : public WorkWindow
58 Graphic aGrf;
59 public:
60 GrfWindow( const Graphic& rGrf );
61 virtual void Paint( const Rectangle& rRect );
64 GrfWindow::GrfWindow( const Graphic& rGrf )
65 : WorkWindow( NULL ),
66 aGrf( rGrf )
68 SetPosSizePixel( Point( 100, 0 ), Size( 300, 300 ));
69 Show();
70 Invalidate();
71 Update();
74 void GrfWindow::Paint( const Rectangle& )
76 aGrf.Draw( this, Point(0,0), GetSizePixel() );
78 #endif
80 static BYTE __FAR_DATA aPal1[ 2 * 4 ] = {
81 0x00, 0x00, 0x00, 0x00, // Schwarz
82 0xFF, 0xFF, 0xFF, 0x00 // Weiss
85 static BYTE __FAR_DATA aPal4[ 16 * 4 ] = {
86 0x00, 0x00, 0x00, 0x00,
87 0x80, 0x00, 0x00, 0x00,
88 0x00, 0x80, 0x00, 0x00,
89 0x80, 0x80, 0x00, 0x00,
90 0x00, 0x00, 0x80, 0x00,
91 0x80, 0x00, 0x80, 0x00,
92 0x00, 0x80, 0x80, 0x00,
93 0x80, 0x80, 0x80, 0x00,
94 0xC0, 0xC0, 0xC0, 0x00,
95 0xFF, 0x00, 0x00, 0x00,
96 0x00, 0xFF, 0x00, 0x00,
97 0xFF, 0xFF, 0x00, 0x00,
98 0x00, 0x00, 0xFF, 0x00,
99 0xFF, 0x00, 0xFF, 0x00,
100 0x00, 0xFF, 0xFF, 0x00,
101 0xFF, 0xFF, 0xFF, 0x00
104 static BYTE __FAR_DATA aPal8[ 256 * 4 ] =
106 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x92, 0x00, 0x00,
107 0x80, 0x92, 0x00, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x80, 0x00, 0xAA, 0x00,
108 0x00, 0x92, 0xAA, 0x00, 0xC1, 0xC1, 0xC1, 0x00, 0xC9, 0xC9, 0xC9, 0x00,
109 0xAA, 0xDB, 0xFF, 0x00, 0x00, 0x49, 0xAA, 0x00, 0x00, 0x49, 0xFF, 0x00,
110 0x00, 0x6D, 0x00, 0x00, 0x00, 0x6D, 0x55, 0x00, 0x00, 0x6D, 0xAA, 0x00,
111 0x00, 0x6D, 0xFF, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x92, 0x55, 0x00,
112 0x00, 0x24, 0xAA, 0x00, 0x00, 0x92, 0xFF, 0x00, 0x00, 0xB6, 0x00, 0x00,
113 0x00, 0xB6, 0x55, 0x00, 0x00, 0xB6, 0xAA, 0x00, 0x00, 0xB6, 0xFF, 0x00,
114 0x00, 0xDB, 0x00, 0x00, 0x00, 0xDB, 0x55, 0x00, 0x00, 0xDB, 0xAA, 0x00,
115 0x00, 0xDB, 0xFF, 0x00, 0xFF, 0xDB, 0xAA, 0x00, 0x00, 0xFF, 0x55, 0x00,
116 0x00, 0xFF, 0xAA, 0x00, 0xFF, 0xFF, 0xAA, 0x00, 0x2B, 0x00, 0x00, 0x00,
117 0x2B, 0x00, 0x55, 0x00, 0x2B, 0x00, 0xAA, 0x00, 0x2B, 0x00, 0xFF, 0x00,
118 0x2B, 0x24, 0x00, 0x00, 0x2B, 0x24, 0x55, 0x00, 0x2B, 0x24, 0xAA, 0x00,
119 0x2B, 0x24, 0xFF, 0x00, 0x2B, 0x49, 0x00, 0x00, 0x2B, 0x49, 0x55, 0x00,
120 0x2B, 0x49, 0xAA, 0x00, 0x2B, 0x49, 0xFF, 0x00, 0x2B, 0x6D, 0x00, 0x00,
121 0x2B, 0x6D, 0x55, 0x00, 0x2B, 0x6D, 0xAA, 0x00, 0x2B, 0x6D, 0xFF, 0x00,
122 0x2B, 0x92, 0x00, 0x00, 0x2B, 0x92, 0x55, 0x00, 0x2B, 0x92, 0xAA, 0x00,
123 0x2B, 0x92, 0xFF, 0x00, 0x2B, 0xB6, 0x00, 0x00, 0x2B, 0xB6, 0x55, 0x00,
124 0x2B, 0xB6, 0xAA, 0x00, 0x2B, 0xB6, 0xFF, 0x00, 0x2B, 0xDB, 0x00, 0x00,
125 0x2B, 0xDB, 0x55, 0x00, 0x2B, 0xDB, 0xAA, 0x00, 0x2B, 0xDB, 0xFF, 0x00,
126 0x2B, 0xFF, 0x00, 0x00, 0x2B, 0xFF, 0x55, 0x00, 0x2B, 0xFF, 0xAA, 0x00,
127 0x2B, 0xFF, 0xFF, 0x00, 0x55, 0x00, 0x00, 0x00, 0x55, 0x00, 0x55, 0x00,
128 0x55, 0x00, 0xAA, 0x00, 0x55, 0x00, 0xFF, 0x00, 0x55, 0x24, 0x00, 0x00,
129 0x55, 0x24, 0x55, 0x00, 0x55, 0x24, 0xAA, 0x00, 0x55, 0x24, 0xFF, 0x00,
130 0x55, 0x49, 0x00, 0x00, 0x55, 0x49, 0x55, 0x00, 0x55, 0x49, 0xAA, 0x00,
131 0x55, 0x49, 0xFF, 0x00, 0x55, 0x6D, 0x00, 0x00, 0x55, 0x6D, 0x55, 0x00,
132 0x55, 0x6D, 0xAA, 0x00, 0x55, 0x6D, 0xFF, 0x00, 0x55, 0x92, 0x00, 0x00,
133 0x55, 0x92, 0x55, 0x00, 0x55, 0x92, 0xAA, 0x00, 0x55, 0x92, 0xFF, 0x00,
134 0x55, 0xB6, 0x00, 0x00, 0x55, 0xB6, 0x55, 0x00, 0x55, 0xB6, 0xAA, 0x00,
135 0x55, 0xB6, 0xFF, 0x00, 0x55, 0xDB, 0x00, 0x00, 0x55, 0xDB, 0x55, 0x00,
136 0x55, 0xDB, 0xAA, 0x00, 0x55, 0xDB, 0xFF, 0x00, 0x55, 0xFF, 0x00, 0x00,
137 0x55, 0xFF, 0x55, 0x00, 0x55, 0xFF, 0xAA, 0x00, 0x55, 0xFF, 0xFF, 0x00,
138 0x00, 0x00, 0x55, 0x00, 0x80, 0x00, 0x55, 0x00, 0x00, 0x24, 0x55, 0x00,
139 0x80, 0x00, 0xFF, 0x00, 0x80, 0x24, 0x00, 0x00, 0x80, 0x24, 0x55, 0x00,
140 0x80, 0x24, 0xAA, 0x00, 0x80, 0x24, 0xFF, 0x00, 0x80, 0x49, 0x00, 0x00,
141 0x80, 0x49, 0x55, 0x00, 0x80, 0x49, 0xAA, 0x00, 0x80, 0x49, 0xFF, 0x00,
142 0x80, 0x6D, 0x00, 0x00, 0x80, 0x6D, 0x55, 0x00, 0x80, 0x6D, 0xAA, 0x00,
143 0x80, 0x6D, 0xFF, 0x00, 0x08, 0x08, 0x08, 0x00, 0x0F, 0x0F, 0x0F, 0x00,
144 0x17, 0x17, 0x17, 0x00, 0x1F, 0x1F, 0x1F, 0x00, 0x27, 0x27, 0x27, 0x00,
145 0x2E, 0x2E, 0x2E, 0x00, 0x36, 0x36, 0x36, 0x00, 0x3E, 0x3E, 0x3E, 0x00,
146 0x46, 0x46, 0x46, 0x00, 0x4D, 0x4D, 0x4D, 0x00, 0x55, 0x55, 0x55, 0x00,
147 0x5D, 0x5D, 0x5D, 0x00, 0x64, 0x64, 0x64, 0x00, 0x6C, 0x6C, 0x6C, 0x00,
148 0x74, 0x74, 0x74, 0x00, 0x7C, 0x7C, 0x7C, 0x00, 0xFF, 0xDB, 0x00, 0x00,
149 0x8B, 0x8B, 0x8B, 0x00, 0x93, 0x93, 0x93, 0x00, 0x9B, 0x9B, 0x9B, 0x00,
150 0xFF, 0xB6, 0xFF, 0x00, 0xAA, 0xAA, 0xAA, 0x00, 0xB2, 0xB2, 0xB2, 0x00,
151 0xB9, 0xB9, 0xB9, 0x00, 0x00, 0x24, 0xFF, 0x00, 0x00, 0x49, 0x00, 0x00,
152 0xD1, 0xD1, 0xD1, 0x00, 0xD8, 0xD8, 0xD8, 0x00, 0xE0, 0xE0, 0xE0, 0x00,
153 0xE8, 0xE8, 0xE8, 0x00, 0xF0, 0xF0, 0xF0, 0x00, 0xFF, 0xB6, 0xAA, 0x00,
154 0xFF, 0xDB, 0xFF, 0x00, 0x80, 0x92, 0x55, 0x00, 0x80, 0x92, 0xAA, 0x00,
155 0x80, 0x92, 0xFF, 0x00, 0x80, 0xB6, 0x00, 0x00, 0x80, 0xB6, 0x55, 0x00,
156 0x80, 0xB6, 0xAA, 0x00, 0x80, 0xB6, 0xFF, 0x00, 0x80, 0xDB, 0x00, 0x00,
157 0x80, 0xDB, 0x55, 0x00, 0x80, 0xDB, 0xAA, 0x00, 0x80, 0xDB, 0xFF, 0x00,
158 0x80, 0xFF, 0x00, 0x00, 0x80, 0xFF, 0x55, 0x00, 0x80, 0xFF, 0xAA, 0x00,
159 0x80, 0xFF, 0xFF, 0x00, 0xAA, 0x00, 0x00, 0x00, 0xAA, 0x00, 0x55, 0x00,
160 0xAA, 0x00, 0xAA, 0x00, 0xAA, 0x00, 0xFF, 0x00, 0xAA, 0x24, 0x00, 0x00,
161 0xAA, 0x24, 0x55, 0x00, 0xAA, 0x24, 0xAA, 0x00, 0xAA, 0x24, 0xFF, 0x00,
162 0xAA, 0x49, 0x00, 0x00, 0xAA, 0x49, 0x55, 0x00, 0xAA, 0x49, 0xAA, 0x00,
163 0xAA, 0x49, 0xFF, 0x00, 0xAA, 0x6D, 0x00, 0x00, 0xAA, 0x6D, 0x55, 0x00,
164 0xAA, 0x6D, 0xAA, 0x00, 0xAA, 0x6D, 0xFF, 0x00, 0xAA, 0x92, 0x00, 0x00,
165 0xAA, 0x92, 0x55, 0x00, 0xAA, 0x92, 0xAA, 0x00, 0xAA, 0x92, 0xFF, 0x00,
166 0xAA, 0xB6, 0x00, 0x00, 0xAA, 0xB6, 0x55, 0x00, 0xAA, 0xB6, 0xAA, 0x00,
167 0xAA, 0xB6, 0xFF, 0x00, 0xAA, 0xDB, 0x00, 0x00, 0xAA, 0xDB, 0x55, 0x00,
168 0xAA, 0xDB, 0xAA, 0x00, 0x00, 0x49, 0x55, 0x00, 0xAA, 0xFF, 0x00, 0x00,
169 0xAA, 0xFF, 0x55, 0x00, 0xAA, 0xFF, 0xAA, 0x00, 0xAA, 0xFF, 0xFF, 0x00,
170 0xD5, 0x00, 0x00, 0x00, 0xD5, 0x00, 0x55, 0x00, 0xD5, 0x00, 0xAA, 0x00,
171 0xD5, 0x00, 0xFF, 0x00, 0xD5, 0x24, 0x00, 0x00, 0xD5, 0x24, 0x55, 0x00,
172 0xD5, 0x24, 0xAA, 0x00, 0xD5, 0x24, 0xFF, 0x00, 0xD5, 0x49, 0x00, 0x00,
173 0xD5, 0x49, 0x55, 0x00, 0xD5, 0x49, 0xAA, 0x00, 0xD5, 0x49, 0xFF, 0x00,
174 0xD5, 0x6D, 0x00, 0x00, 0xD5, 0x6D, 0x55, 0x00, 0xD5, 0x6D, 0xAA, 0x00,
175 0xD5, 0x6D, 0xFF, 0x00, 0xD5, 0x92, 0x00, 0x00, 0xD5, 0x92, 0x55, 0x00,
176 0xD5, 0x92, 0xAA, 0x00, 0xD5, 0x92, 0xFF, 0x00, 0xD5, 0xB6, 0x00, 0x00,
177 0xD5, 0xB6, 0x55, 0x00, 0xD5, 0xB6, 0xAA, 0x00, 0xD5, 0xB6, 0xFF, 0x00,
178 0xD5, 0xDB, 0x00, 0x00, 0xD5, 0xDB, 0x55, 0x00, 0xD5, 0xDB, 0xAA, 0x00,
179 0xD5, 0xDB, 0xFF, 0x00, 0xD5, 0xFF, 0x00, 0x00, 0xD5, 0xFF, 0x55, 0x00,
180 0xD5, 0xFF, 0xAA, 0x00, 0xD5, 0xFF, 0xFF, 0x00, 0xFF, 0xDB, 0x55, 0x00,
181 0xFF, 0x00, 0x55, 0x00, 0xFF, 0x00, 0xAA, 0x00, 0xFF, 0xFF, 0x55, 0x00,
182 0xFF, 0x24, 0x00, 0x00, 0xFF, 0x24, 0x55, 0x00, 0xFF, 0x24, 0xAA, 0x00,
183 0xFF, 0x24, 0xFF, 0x00, 0xFF, 0x49, 0x00, 0x00, 0xFF, 0x49, 0x55, 0x00,
184 0xFF, 0x49, 0xAA, 0x00, 0xFF, 0x49, 0xFF, 0x00, 0xFF, 0x6D, 0x00, 0x00,
185 0xFF, 0x6D, 0x55, 0x00, 0xFF, 0x6D, 0xAA, 0x00, 0xFF, 0x6D, 0xFF, 0x00,
186 0xFF, 0x92, 0x00, 0x00, 0xFF, 0x92, 0x55, 0x00, 0xFF, 0x92, 0xAA, 0x00,
187 0xFF, 0x92, 0xFF, 0x00, 0xFF, 0xB6, 0x00, 0x00, 0xFF, 0xB6, 0x55, 0x00,
188 0xF7, 0xF7, 0xF7, 0x00, 0xA2, 0xA2, 0xA2, 0x00, 0x83, 0x83, 0x83, 0x00,
189 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00,
190 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00,
191 0xFF, 0xFF, 0xFF, 0x00
195 /* \f */
198 inline long SwapLong( long n )
200 #ifndef OSL_LITENDIAN
201 return SWAPLONG( n );
202 #else
203 return n;
204 #endif
207 inline short SwapShort( short n )
209 #ifndef OSL_LITENDIAN
210 return SWAPSHORT( n );
211 #else
212 return n;
213 #endif
217 static void WriteBMPHeader( SvStream& rStream,
218 const SvxRTFPictureType& rPicType )
220 ULONG n4Width = rPicType.nWidth;
221 ULONG n4Height = rPicType.nHeight;
222 USHORT n4ColBits = rPicType.nBitsPerPixel;
224 USHORT nColors = (1 << n4ColBits); // Anzahl der Farben ( 1, 16, 256 )
225 USHORT nWdtOut = rPicType.nWidthBytes;
226 if( !nWdtOut )
227 nWdtOut = (USHORT)((( n4Width * n4ColBits + 31 ) / 32 ) * 4 );
229 long nOffset = 14 + 40; // BMP_FILE_HD_SIZ + sizeof(*pBmpInfo);
230 if( 256 >= nColors )
231 nOffset += nColors * 4;
232 long nSize = nOffset + nWdtOut * n4Height;
233 rStream << "BM" // = "BM"
234 << SwapLong(nSize) // Filesize in Bytes
235 << SwapShort(0) // Reserviert
236 << SwapShort(0) // Reserviert
237 << SwapLong(nOffset); // Offset?
239 rStream << SwapLong(40) // sizeof( BmpInfo )
240 << SwapLong(n4Width)
241 << SwapLong(n4Height)
242 << (USHORT)1
243 << n4ColBits
244 << SwapLong(0)
245 << SwapLong(0)
246 << SwapLong( rPicType.nGoalWidth
247 ? rPicType.nGoalWidth * 1000L / 254L
248 : 0 ) // DPI in Pixel per Meter
249 << SwapLong( rPicType.nGoalHeight
250 ? rPicType.nGoalHeight * 1000L / 254L // dito
251 : 0 )
252 << SwapLong(0)
253 << SwapLong(0);
256 switch( rPicType.nBitsPerPixel )
258 case 1: rStream.Write( aPal1, sizeof( aPal1 )); break;
259 case 4: rStream.Write( aPal4, sizeof( aPal4 )); break;
260 case 8: rStream.Write( aPal8, sizeof( aPal8 )); break;
264 /* \f */
266 // wandel die ASCII-HexCodes in binaere Zeichen um. Werden
267 // ungueltige Daten gefunden (Zeichen ausser 0-9|a-f|A-F, so
268 // wird USHRT_MAX returnt, ansonsten die Anzahl der umgewandelten Ze.
269 xub_StrLen SvxRTFParser::HexToBin( String& rToken )
271 // dann mache aus den Hex-Werten mal "Binare Daten"
272 // (missbrauche den String als temp Buffer)
273 if( rToken.Len() & 1 ) // ungerade Anzahl, mit 0 auffuellen
274 rToken += '0';
276 xub_StrLen n, nLen;
277 sal_Unicode nVal;
278 BOOL bValidData = TRUE;
279 const sal_Unicode* pStr = rToken.GetBufferAccess();
280 sal_Char* pData = (sal_Char*)pStr;
281 for( n = 0, nLen = rToken.Len(); n < nLen; ++n, ++pStr )
283 if( ((nVal = *pStr) >= '0') && ( nVal <= '9') )
284 nVal -= '0';
285 else if( (nVal >= 'A') && (nVal <= 'F') )
286 nVal -= 'A' - 10;
287 else if( (nVal >= 'a') && (nVal <= 'f') )
288 nVal -= 'a' - 10;
289 else
291 DBG_ASSERT( !this, "ungueltiger Hex-Wert" );
292 bValidData = FALSE;
293 break;
296 if( n & 1 )
297 *(pData++) |= nVal & 0x0f;
298 else
299 *(pData) = sal::static_int_cast< char >( ( nVal << 4 ) & 0xf0 );
301 // the len div 2, because 2 character are one byte
302 return bValidData ? nLen / 2 : STRING_NOTFOUND;
305 BOOL SvxRTFParser::ReadBmpData( Graphic& rGrf, SvxRTFPictureType& rPicType )
307 // die alten Daten loeschen
308 rGrf.Clear();
309 // ULONG nBmpSize = 0;
311 rtl_TextEncoding eOldEnc = GetSrcEncoding();
312 SetSrcEncoding( RTL_TEXTENCODING_MS_1252 );
314 const sal_Char* pFilterNm = 0;
315 SvCacheStream* pTmpFile = 0;
317 int nToken = 0;
318 bool bValidBmp = true, bFirstTextToken = true;
319 int _nOpenBrakets = 1, // die erste wurde schon vorher erkannt !!
320 nValidDataBraket = 1;
322 if( RTF_SHPPICT == GetStackPtr(0)->nTokenId )
323 ++nValidDataBraket;
325 while( _nOpenBrakets && IsParserWorking() && bValidBmp )
327 nToken = GetNextToken();
328 USHORT nVal = USHORT( nTokenValue );
329 switch( nToken )
331 case '}': --_nOpenBrakets; break;
332 case '{':
334 if( RTF_IGNOREFLAG != GetNextToken() )
335 nToken = SkipToken( -1 );
336 else if( RTF_UNKNOWNCONTROL != GetNextToken() )
337 nToken = SkipToken( -2 );
338 else
340 // gleich herausfiltern
341 ReadUnknownData();
342 nToken = GetNextToken();
343 if( '}' != nToken )
344 eState = SVPAR_ERROR;
345 break;
347 ++_nOpenBrakets;
349 break;
351 case RTF_MACPICT:
353 rPicType.eStyle = SvxRTFPictureType::MAC_QUICKDRAW;
354 // Mac-Pict bekommt einen leeren Header voran
355 pTmpFile = new SvCacheStream;
356 ByteString aStr;
357 aStr.Fill( 512, '\0' );
358 pTmpFile->Write( aStr.GetBuffer(), aStr.Len() );
359 pFilterNm = "PCT";
361 break;
363 case RTF_EMFBLIP:
364 case RTF_WMETAFILE:
365 case RTF_PNGBLIP:
366 case RTF_JPEGBLIP:
367 case RTF_WBITMAP:
368 case RTF_OSMETAFILE:
369 case RTF_DIBITMAP:
371 switch( nToken )
373 case RTF_EMFBLIP:
374 rPicType.eStyle = SvxRTFPictureType::ENHANCED_MF;
375 pFilterNm = "EMF";
376 break;
377 case RTF_WMETAFILE:
378 rPicType.eStyle = SvxRTFPictureType::WIN_METAFILE;
379 pFilterNm = "WMF";
380 break;
381 case RTF_PNGBLIP:
382 rPicType.eStyle = SvxRTFPictureType::RTF_PNG;
383 pFilterNm = "PNG";
384 break;
385 case RTF_JPEGBLIP:
386 rPicType.eStyle = SvxRTFPictureType::RTF_JPG;
387 pFilterNm = "JPG";
388 break;
390 case RTF_WBITMAP:
391 rPicType.eStyle = SvxRTFPictureType::RTF_BITMAP;
392 break;
393 case RTF_OSMETAFILE:
394 rPicType.eStyle = SvxRTFPictureType::OS2_METAFILE;
395 break;
396 case RTF_DIBITMAP:
397 rPicType.eStyle = SvxRTFPictureType::RTF_DI_BMP;
398 break;
401 rPicType.nType = nVal;
402 pTmpFile = new SvCacheStream;
404 break;
406 case RTF_PICW: rPicType.nWidth = nVal; break;
407 case RTF_PICH: rPicType.nHeight = nVal; break;
408 case RTF_WBMBITSPIXEL: rPicType.nBitsPerPixel = nVal; break;
409 case RTF_WBMPLANES: rPicType.nPlanes = nVal; break;
410 case RTF_WBMWIDTHBYTES: rPicType.nWidthBytes = nVal; break;
411 case RTF_PICWGOAL: rPicType.nGoalWidth = nVal; break;
412 case RTF_PICHGOAL: rPicType.nGoalHeight = nVal; break;
413 case RTF_BIN:
414 rPicType.nMode = SvxRTFPictureType::BINARY_MODE;
415 rPicType.uPicLen = nTokenValue;
416 if (rPicType.uPicLen)
418 ULONG nPos = rStrm.Tell();
419 nPos = nPos;
420 rStrm.SeekRel(-1);
421 sal_uInt8 aData[4096];
422 ULONG nSize = sizeof(aData);
424 while (rPicType.uPicLen > 0)
426 if (rPicType.uPicLen < nSize)
427 nSize = rPicType.uPicLen;
429 rStrm.Read(aData, nSize);
430 pTmpFile->Write(aData, nSize);
431 rPicType.uPicLen -= nSize;
433 nNextCh = GetNextChar();
434 bValidBmp = !pTmpFile->GetError();
435 nPos = rStrm.Tell();
436 nPos = nPos;
438 break;
439 case RTF_PICSCALEX: rPicType.nScalX = nVal; break;
440 case RTF_PICSCALEY: rPicType.nScalY = nVal; break;
441 case RTF_PICSCALED: break;
443 case RTF_PICCROPT: rPicType.nCropT = (short)nTokenValue; break;
444 case RTF_PICCROPB: rPicType.nCropB = (short)nTokenValue; break;
445 case RTF_PICCROPL: rPicType.nCropL = (short)nTokenValue; break;
446 case RTF_PICCROPR: rPicType.nCropR = (short)nTokenValue; break;
448 case RTF_TEXTTOKEN:
449 // JP 26.06.98: Bug #51719# - nur TextToken auf 1. Ebene
450 // auswerten. Alle anderen sind irgendwelche
451 // nicht auszuwertende Daten
452 if( nValidDataBraket != _nOpenBrakets )
453 break;
455 if( bFirstTextToken )
457 switch( rPicType.eStyle )
459 case SvxRTFPictureType::RTF_BITMAP:
460 // erstmal die Header und Info-Struktur schreiben
461 if( pTmpFile )
462 ::WriteBMPHeader( *pTmpFile, rPicType );
463 break;
464 default:
465 break;
467 bFirstTextToken = FALSE;
470 if( pTmpFile && SvxRTFPictureType::HEX_MODE == rPicType.nMode )
472 xub_StrLen nTokenLen = HexToBin( aToken );
473 if( STRING_NOTFOUND == nTokenLen )
474 bValidBmp = FALSE;
475 else
477 pTmpFile->Write( (sal_Char*)aToken.GetBuffer(),
478 nTokenLen );
479 bValidBmp = 0 == pTmpFile->GetError();
482 break;
486 if (pTmpFile)
488 //#i20775#
489 if (pTmpFile->Tell() == 0)
490 bValidBmp = false;
492 if( bValidBmp )
494 GraphicFilter* pGF = ::GetGrfFilter();
495 USHORT nImportFilter = GRFILTER_FORMAT_DONTKNOW;
497 if( pFilterNm )
499 String sTmp;
500 for( USHORT n = pGF->GetImportFormatCount(); n; )
502 sTmp = pGF->GetImportFormatShortName( --n );
503 if( sTmp.EqualsAscii( pFilterNm ))
505 nImportFilter = n;
506 break;
511 String sTmpStr;
512 WMF_APMFILEHEADER aAPMHeader;
513 aAPMHeader.left=0;
514 aAPMHeader.top=0;
515 aAPMHeader.right=rPicType.nWidth;
516 aAPMHeader.bottom=rPicType.nHeight;
518 WMF_APMFILEHEADER *pAPMHeader=(aAPMHeader.right>0 && aAPMHeader.bottom>0?&aAPMHeader:NULL);
519 pTmpFile->Seek( STREAM_SEEK_TO_BEGIN );
520 bValidBmp = 0 == pGF->ImportGraphic( rGrf, sTmpStr, *pTmpFile, nImportFilter, NULL, 0, pAPMHeader );
522 delete pTmpFile;
525 if( !bValidBmp )
527 rGrf.Clear();
528 //TODO If nToken were not initialized to 0 above, it would potentially
529 // be used uninitialized here (if IsParserWorking() is false at the
530 // start of the while loop above):
531 if( '}' != nToken )
532 SkipGroup();
534 else
536 switch( rPicType.eStyle )
538 //?? ENHANCED_MF, // in den Pict.Daten steht ein Enhanced-Metafile
539 case SvxRTFPictureType::RTF_PNG:
540 case SvxRTFPictureType::RTF_JPG:
542 const MapMode aMap( MAP_100TH_MM );
543 Size aSize( rGrf.GetPrefSize() );
544 if( MAP_PIXEL == rGrf.GetPrefMapMode().GetMapUnit() )
545 aSize = Application::GetDefaultDevice()->PixelToLogic(
546 aSize, aMap );
547 else
548 aSize = OutputDevice::LogicToLogic( aSize,
549 rGrf.GetPrefMapMode(), aMap );
550 rPicType.nWidth = sal::static_int_cast< USHORT >(aSize.Width());
551 rPicType.nHeight = sal::static_int_cast< USHORT >(
552 aSize.Height());
554 break;
555 default:
556 break;
559 #ifdef DEBUG_JP
560 new GrfWindow( rGrf );
561 #endif
563 SetSrcEncoding( eOldEnc );
565 SkipToken( -1 ); // die schliesende Klammer wird "oben" ausgewertet
566 return bValidBmp;
569 /* vi:set tabstop=4 shiftwidth=4 expandtab: */