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